breaking everything that was working. cannot even start a race now, need to rewrite the network manager and part of the race startup sequence

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13032 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hilnius 2013-06-29 22:57:18 +00:00
parent 36673a2112
commit 613e97d0d6
76 changed files with 3015 additions and 2585 deletions

View File

@ -41,7 +41,7 @@ XMLNode::XMLNode(const std::string &filename)
m_file_name = filename;
io::IXMLReader *xml = file_manager->createXMLReader(filename);
if (xml == NULL)
{
throw std::runtime_error("Cannot find file "+filename);
@ -597,4 +597,4 @@ bool XMLNode::hasChildNamed(const char* name) const
if (m_nodes[i]->getName() == name) return true;
}
return false;
}
}

View File

@ -33,7 +33,6 @@
#include "karts/kart_properties.hpp"
#include "modes/three_strikes_battle.hpp"
#include "modes/world.hpp"
#include "network/race_state.hpp"
#include "network/network_manager.hpp"
#include "utils/constants.hpp"
@ -260,11 +259,13 @@ void Attachment::hitBanana(Item *item, int new_attachment)
// Save the information about the attachment in the race state
// so that the clients can be updated.
if(network_manager->getMode()==NetworkManager::NW_SERVER)
if(NetworkManager::getInstance()->isPlayingOnline()) // if we're online
{
/*
race_state->itemCollected(m_kart->getWorldKartId(),
item->getItemId(),
new_attachment);
new_attachment);*/
//NETWORK_UPDATE_PLZ
}
if (add_a_new_item)

View File

@ -38,7 +38,6 @@
#include "karts/abstract_kart.hpp"
#include "karts/explosion_animation.hpp"
#include "modes/world.hpp"
#include "network/flyable_info.hpp"
#include "physics/physics.hpp"
#include "tracks/track.hpp"
#include "utils/constants.hpp"
@ -416,11 +415,13 @@ bool Flyable::updateAndDelete(float dt)
*/
void Flyable::updateFromServer(const FlyableInfo &f, float dt)
{
/*
setXYZ(f.m_xyz);
setRotation(f.m_rotation);
*/
// Update the graphical position
Moveable::update(dt);
} // updateFromServer
// ----------------------------------------------------------------------------

View File

@ -19,6 +19,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//NETWORK_UPDATE_PLZ
#ifndef HEADER_FLYABLE_HPP
#define HEADER_FLYABLE_HPP

View File

@ -291,7 +291,7 @@ void ItemManager::collectedItem(Item *item, AbstractKart *kart, int add_info)
void ItemManager::checkItemHit(AbstractKart* kart)
{
// Only do this on the server
if(network_manager->getMode()==NetworkManager::NW_CLIENT) return;
if(NetworkManager::getInstance()->isServer()) return;
// We could use m_items_in_quads to to check for item hits: take the quad
// of the graph node of the kart, and only check items in that quad. But

View File

@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//NETWORK_UPDATE_PLZ
#include "items/powerup.hpp"
#include "audio/sfx_base.hpp"
@ -30,8 +31,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"

View File

@ -16,6 +16,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//NETWORK_UPDATE_PLZ
#include "items/projectile_manager.hpp"
#include "graphics/explosion.hpp"
@ -27,7 +29,6 @@
#include "items/powerup.hpp"
#include "items/rubber_ball.hpp"
#include "network/network_manager.hpp"
#include "network/race_state.hpp"
ProjectileManager *projectile_manager=0;
@ -66,7 +67,8 @@ void ProjectileManager::cleanup()
/** General projectile update call. */
void ProjectileManager::update(float dt)
{
if(network_manager->getMode()==NetworkManager::NW_CLIENT)
if(NetworkManager::getInstance()->isClient())
{
updateClient(dt);
}
@ -101,21 +103,23 @@ void ProjectileManager::update(float dt)
void ProjectileManager::updateServer(float dt)
{
// First update all projectiles on the track
if(network_manager->getMode()!=NetworkManager::NW_NONE)
if(NetworkManager::getInstance()->isPlayingOnline()) //network_manager->getMode()!=NetworkManager::NW_NONE)
{
race_state->setNumFlyables(m_active_projectiles.size());
//race_state->setNumFlyables(m_active_projectiles.size());
}
Projectiles::iterator p = m_active_projectiles.begin();
while(p!=m_active_projectiles.end())
{
bool can_be_deleted = (*p)->updateAndDelete(dt);
if(network_manager->getMode()!=NetworkManager::NW_NONE)
if(NetworkManager::getInstance()->isPlayingOnline()) //network_manager->getMode()!=NetworkManager::NW_NONE)
{
race_state->setFlyableInfo(p-m_active_projectiles.begin(),
/*race_state->setFlyableInfo(p-m_active_projectiles.begin(),
FlyableInfo((*p)->getXYZ(),
(*p)->getRotation(),
can_be_deleted) );
can_be_deleted) );*/
}
if(can_be_deleted)
{
@ -130,6 +134,7 @@ void ProjectileManager::updateServer(float dt)
else
p++;
} // while p!=m_active_projectiles.end()
} // updateServer
// -----------------------------------------------------------------------------
@ -138,6 +143,7 @@ void ProjectileManager::updateServer(float dt)
* (i.e. position, hit effects etc) */
void ProjectileManager::updateClient(float dt)
{
/*
unsigned int num_projectiles = race_state->getNumFlyables();
if(num_projectiles != m_active_projectiles.size())
fprintf(stderr, "Warning: num_projectiles %d active %d\n",
@ -154,7 +160,7 @@ void ProjectileManager::updateClient(float dt)
(*i)->hit(NULL);
}
} // for i in m_active_projectiles
*/
} // updateClient
// -----------------------------------------------------------------------------
Flyable *ProjectileManager::newProjectile(AbstractKart *kart, Track* track,

View File

@ -19,9 +19,9 @@
#ifndef HEADER_KART_CONTROL_HPP
#define HEADER_KART_CONTROL_HPP
#include "network/message.hpp"
//NETWORK_UPDATE_PLZ
/**
/**
* \ingroup controller
*/
class KartControl
@ -52,15 +52,6 @@ public:
reset();
}
// ------------------------------------------------------------------------
/** Construct kart control from a Message (i.e. unserialise) */
KartControl(Message *m)
{
m_steer = m->getFloat();
m_accel = m->getFloat();
char c = m->getChar();
setButtonsCompressed(c);
} // KartControl(Message*)
// ------------------------------------------------------------------------
/** Resets all controls. */
void reset()
{
@ -74,17 +65,6 @@ public:
m_look_back = false;
} // reset
// ------------------------------------------------------------------------
/** Return the serialised size in bytes. */
static int getLength() { return 9; }
// ------------------------------------------------------------------------
/** Serialises the kart control into a message. */
void serialise(Message *m) const
{
m->addFloat(m_steer);
m->addFloat(m_accel);
m->addChar(getButtonsCompressed());
} // compress
// ------------------------------------------------------------------------
void uncompress(char *c)
{
m_steer = ((float*)c)[0];

View File

@ -298,7 +298,7 @@ void SkiddingAI::update(float dt)
#endif
// The client does not do any AI computations.
if(network_manager->getMode()==NetworkManager::NW_CLIENT)
if(NetworkManager::getInstance()->isClient())
{
AIBaseController::update(dt);
return;

View File

@ -56,7 +56,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"
@ -78,6 +77,8 @@
# include <math.h>
#endif
//NETWORK_UPDATE_PLZ
/** The kart constructor.
* \param ident The identifier for the kart model to use.
* \param position The position (or rank) for this kart (between 1 and
@ -867,11 +868,11 @@ void Kart::collectedItem(Item *item, int add_info)
// Attachments and powerups are stored in the corresponding
// functions (hit{Red,Green}Item), so only coins need to be
// stored here.
if(network_manager->getMode()==NetworkManager::NW_SERVER &&
/*if(NetworkManager::getInstance()->isServer() &&
(type==Item::ITEM_NITRO_BIG || type==Item::ITEM_NITRO_SMALL) )
{
race_state->itemCollected(getWorldKartId(), item->getItemId());
}
}*/
if ( m_collected_energy > m_kart_properties->getNitroMax())
m_collected_energy = m_kart_properties->getNitroMax();
@ -1012,9 +1013,9 @@ void Kart::update(float dt)
// Store the actual kart controls at the start of update in the server
// state. This makes it easier to reset some fields when they are not used
// anymore (e.g. controls.fire).
if(network_manager->getMode()==NetworkManager::NW_SERVER)
if(NetworkManager::getInstance()->isServer())
{
race_state->storeKartControls(*this);
//race_state->storeKartControls(*this);
}
if (!m_flying)
@ -1815,10 +1816,8 @@ void Kart::updatePhysics(float dt)
updateSliding();
// Only compute the current speed if this is not the client. On a client the
// speed is actually received from the server.
if(network_manager->getMode()!=NetworkManager::NW_CLIENT)
m_speed = getVehicle()->getRigidBody()->getLinearVelocity().length();
// Compute the speed of the kart.
m_speed = getVehicle()->getRigidBody()->getLinearVelocity().length();
// calculate direction of m_speed
const btTransform& chassisTrans = getVehicle()->getChassisWorldTransform();

View File

@ -169,6 +169,8 @@
#include "modes/demo_world.hpp"
#include "modes/profile_world.hpp"
#include "network/network_manager.hpp"
#include "network/client_network_manager.hpp"
#include "network/server_network_manager.hpp"
#include "race/grand_prix_manager.hpp"
#include "race/highscore_manager.hpp"
#include "race/history.hpp"
@ -683,22 +685,17 @@ int handleCmdLine(int argc, char **argv)
}
else if(sscanf(argv[i], "--server=%d",&n)==1)
{
network_manager->setMode(NetworkManager::NW_SERVER);
NetworkManager::getInstance<ServerNetworkManager>(); //create the server
UserConfigParams::m_server_port = n;
}
else if( !strcmp(argv[i], "--server") )
{
network_manager->setMode(NetworkManager::NW_SERVER);
NetworkManager::getInstance<ServerNetworkManager>();
}
else if( sscanf(argv[i], "--port=%d", &n) )
{
UserConfigParams::m_server_port=n;
}
else if( sscanf(argv[i], "--client=%1023s", s) )
{
network_manager->setMode(NetworkManager::NW_CLIENT);
UserConfigParams::m_server_address=s;
}
else if ( sscanf(argv[i], "--gfx=%d", &n) )
{
if (n)
@ -1142,9 +1139,10 @@ void initRest()
kart_properties_manager = new KartPropertiesManager();
projectile_manager = new ProjectileManager ();
powerup_manager = new PowerupManager ();
// If the server has been created (--server option), this will do nothing:
NetworkManager::getInstance<ClientNetworkManager>();
attachment_manager = new AttachmentManager ();
highscore_manager = new HighscoreManager ();
network_manager = new NetworkManager ();
KartPropertiesManager::addKartSearchDir(
file_manager->getAddonsFile("karts/"));
track_manager->addTrackSearchDir(
@ -1191,7 +1189,7 @@ void cleanSuperTuxKart()
INetworkHttp::destroy();
if(news_manager) delete news_manager;
if(addons_manager) delete addons_manager;
if(network_manager) delete network_manager;
NetworkManager::kill();
if(grand_prix_manager) delete grand_prix_manager;
if(highscore_manager) delete highscore_manager;
if(attachment_manager) delete attachment_manager;
@ -1449,7 +1447,7 @@ int main(int argc, char *argv[] )
{
// This will setup the race manager etc.
history->Load();
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
race_manager->startNew(false);
main_loop->run();
// well, actually run() will never return, since
@ -1458,20 +1456,6 @@ int main(int argc, char *argv[] )
exit(-3);
}
// Initialise connection in case that a command line option was set
// configuring a client or server. Otherwise this function does nothing
// here (and will be called again from the network gui).
if(!network_manager->initialiseConnections())
{
Log::error("main", "Problems initialising network connections,\n"
"Running in non-network mode.");
}
// On the server start with the network information page for now
if(network_manager->getMode()==NetworkManager::NW_SERVER)
{
// TODO - network menu
//menu_manager->pushMenu(MENUID_NETWORK_GUI);
}
// Not replaying
// =============
if(!ProfileWorld::isProfileMode())
@ -1481,7 +1465,7 @@ int main(int argc, char *argv[] )
// Quickstart (-N)
// ===============
// all defaults are set in InitTuxkart()
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
race_manager->startNew(false);
}
}
@ -1491,7 +1475,7 @@ int main(int argc, char *argv[] )
// =========
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD);
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
race_manager->startNew(false);
}
main_loop->run();

View File

@ -98,17 +98,17 @@ void MainLoop::updateRace(float dt)
// Client: send current controls to server
// But don't do this if the race is in finish phase (otherwise
// messages can be mixed up in the race manager)
if(!World::getWorld()->isFinishPhase())
network_manager->sendUpdates();
/*if(!World::getWorld()->isFinishPhase())
network_manager->sendUpdates();*/
if(ProfileWorld::isProfileMode()) dt=1.0f/60.0f;
// Again, only receive updates if the race isn't over - once the
// race results are displayed (i.e. game is in finish phase)
// messages must be handled by the normal update of the network
// manager
if(!World::getWorld()->isFinishPhase())
network_manager->receiveUpdates();
/*if(!World::getWorld()->isFinishPhase())
network_manager->receiveUpdates();*/
World::getWorld()->updateWorld(dt);
} // updateRace
@ -127,13 +127,13 @@ void MainLoop::run()
m_prev_time = m_curr_time;
float dt = getLimitedDt();
network_manager->update(dt);
// network_manager->update(dt);
if (World::getWorld()) // race is active if world exists
{
// Busy wait if race_manager is active (i.e. creating of world is done)
// till all clients have reached this state.
if (network_manager->getState()==NetworkManager::NS_READY_SET_GO_BARRIER) continue;
//if (network_manager->getState()==NetworkManager::NS_READY_SET_GO_BARRIER) continue;
updateRace(dt);
} // if race is active

View File

@ -149,7 +149,7 @@ bool DemoWorld::updateIdleTimeAndStartDemo(float dt)
m_do_demo = true;
race_manager->setNumKarts(m_num_karts);
race_manager->setLocalKartInfo(0, "tux");
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
race_manager->startSingleRace(m_demo_tracks[0], m_num_laps, false);
m_demo_tracks.push_back(m_demo_tracks[0]);
m_demo_tracks.erase(m_demo_tracks.begin());

View File

@ -322,10 +322,10 @@ void LinearWorld::newLap(unsigned int kart_index)
// A client does not detect race finished by itself, it will
// receive a message from the server. So a client does not do
// anything here.
if(network_manager->getMode()!=NetworkManager::NW_CLIENT)
/*if(network_manager->getMode()!=NetworkManager::NW_CLIENT)
{
kart->finishedRace(getTime());
}
}*/
}
float time_per_lap;
if (kart_info.m_race_lap == 1) // just completed first lap

View File

@ -83,7 +83,7 @@ void OverWorld::enterOverWorld()
->setSinglePlayer( StateManager::get()->getActivePlayer(0) );
StateManager::get()->enterGameState();
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
race_manager->startNew(false);
if(race_manager->haveKartLastPositionOnOverworld()){
OverWorld *ow = (OverWorld*)World::getWorld();

View File

@ -42,8 +42,6 @@
#include "karts/kart_properties_manager.hpp"
#include "modes/overworld.hpp"
#include "modes/profile_world.hpp"
#include "network/network_manager.hpp"
#include "network/race_state.hpp"
#include "physics/btKart.hpp"
#include "physics/physics.hpp"
#include "physics/triangle_mesh.hpp"
@ -119,7 +117,7 @@ World::World() : WorldStatus(), m_clear_color(255,100,101,140)
*/
void World::init()
{
race_state = new RaceState();
// race_state = new RaceState();
m_faster_music_active = false;
m_fastest_kart = 0;
m_eliminated_karts = 0;
@ -175,7 +173,7 @@ void World::init()
if(ReplayPlay::get())
ReplayPlay::get()->Load();
network_manager->worldLoaded();
// network_manager->worldLoaded();
powerup_manager->updateWeightsForRace(num_karts);
} // init
@ -361,7 +359,7 @@ World::~World()
// gui and this must be deleted.
delete m_race_gui;
}
delete race_state;
// delete race_state;
for ( unsigned int i = 0 ; i < m_karts.size() ; i++ )
delete m_karts[i];
@ -747,7 +745,7 @@ void World::updateWorld(float dt)
->setSinglePlayer( StateManager::get()->getActivePlayer(0) );
StateManager::get()->enterGameState();
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
race_manager->startNew(false);
}
else
@ -801,10 +799,10 @@ void World::update(float dt)
if(history->replayHistory()) dt=history->getNextDelta();
WorldStatus::update(dt);
// Clear race state so that new information can be stored
race_state->clear();
// race_state->clear();
if(network_manager->getMode()!=NetworkManager::NW_CLIENT &&
!history->dontDoPhysics())
// if(network_manager->getMode()!=NetworkManager::NW_CLIENT &&
// !history->dontDoPhysics())
{
m_physics->update(dt);
}

View File

@ -112,8 +112,8 @@ void WorldStatus::enterRaceOverState()
*/
void WorldStatus::terminateRace()
{
if(network_manager->getMode()==NetworkManager::NW_SERVER)
network_manager->sendRaceResults();
// if(network_manager->getMode()==NetworkManager::NW_SERVER)
// network_manager->sendRaceResults();
} // terminateRace
//-----------------------------------------------------------------------------

View File

@ -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 <string>
#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

View File

@ -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<std::string> 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<std::string> all_karts;
all_karts = getStringVector();
kart_properties_manager->setUnavailableKarts(all_karts);
}
}; // CharacterInfoMessage
#endif

View File

@ -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

View File

@ -0,0 +1,128 @@
//
// 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 <stdio.h>
ClientNetworkManager::ClientNetworkManager()
{
}
ClientNetworkManager::~ClientNetworkManager()
{
}
void ClientNetworkManager::run()
{
if (enet_initialize() != 0)
{
printf("Could not initialize enet.\n");
return;
}
m_localhost = new STKHost();
m_localhost->setupClient(1, 2, 0, 0);
m_localhost->startListening();
NetworkManager::run();
}
bool ClientNetworkManager::connectToHost(std::string serverNickname)
{
printf("_NetworkInterface>Starting the connection to host protocol\n");
// step 1 : retreive public address
Protocol* protocol = new GetPublicAddress(&m_public_address);
ProtocolManager::getInstance()->requestStart(protocol);
while (ProtocolManager::getInstance()->getProtocolState(protocol) != PROTOCOL_STATE_TERMINATED )
{
}
printf("_NetworkInterface> The public address is known.\n");
// step 2 : show the public address for others (here, the server)
ShowPublicAddress* spa = new ShowPublicAddress(NULL);
spa->setPassword(m_player_login.password);
spa->setUsername(m_player_login.username);
spa->setPublicAddress(m_public_address.ip, m_public_address.port);
ProtocolManager::getInstance()->requestStart(spa);
while (ProtocolManager::getInstance()->getProtocolState(spa) != PROTOCOL_STATE_TERMINATED )
{
}
printf("_NetworkInterface> The public address is being shown online.\n");
// step 3 : get the server's addres.
TransportAddress addr;
GetPeerAddress* gpa = new GetPeerAddress(&addr);
gpa->setPeerName(serverNickname);
ProtocolManager::getInstance()->requestStart(gpa);
while (ProtocolManager::getInstance()->getProtocolState(gpa) != PROTOCOL_STATE_TERMINATED )
{
}
printf("_NetworkInterface> The public address of the server is known.\n");
// step 4 : connect to the server
ConnectToServer* cts = new ConnectToServer(NULL);
cts->setServerAddress(addr.ip, addr.port);
ProtocolManager::getInstance()->requestStart(cts);
while (ProtocolManager::getInstance()->getProtocolState(cts) != PROTOCOL_STATE_TERMINATED )
{
}
bool success = false;
if (m_localhost->isConnectedTo(TransportAddress(addr.ip, addr.port)))
{
success = true;
printf("_NetworkInterface> CONNECTION SUCCES : YOU ARE NOW CONNECTED TO A SERVER.\n");
}
else
{
printf("_NetworkInterface> We are NOT connected to the server.\n");
}
// step 5 : hide our public address
HidePublicAddress* hpa = new HidePublicAddress(NULL);
hpa->setPassword(m_player_login.password);
hpa->setUsername(m_player_login.username);
ProtocolManager::getInstance()->requestStart(hpa);
while (ProtocolManager::getInstance()->getProtocolState(hpa) != PROTOCOL_STATE_TERMINATED )
{
}
printf("_NetworkInterface> The public address is now hidden online.\n");
return success;
}
void ClientNetworkManager::packetReceived(char* data)
{
printf("ClientNetworkManager::packetReceived()\n");
puts(data);
}
void ClientNetworkManager::sendPacket(char* data)
{
if (m_peers.size() > 1)
printf("Ambiguous send of data\n");
m_peers[0]->sendPacket(data);
}
STKPeer* ClientNetworkManager::getPeer()
{
return m_peers[0];
}

View File

@ -0,0 +1,48 @@
//
// 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_manager.hpp"
class ClientNetworkManager : public NetworkManager
{
friend class Singleton<NetworkManager>;
public:
static ClientNetworkManager* getInstance()
{
return Singleton<NetworkManager>::getInstance<ClientNetworkManager>();
}
virtual void run();
bool connectToHost(std::string serverNickname);
virtual void packetReceived(char* data);
virtual void sendPacket(char* data);
STKPeer* getPeer();
virtual bool isServer() { return false; }
protected:
ClientNetworkManager();
virtual ~ClientNetworkManager();
};
#endif // CLIENT_NETWORK_MANAGER_HPP

View File

@ -1,78 +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 <string>
#include <vector>
#include <sstream>
#ifndef WIN32
# include <unistd.h>
#endif
#include "config/user_config.hpp"
#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<std::string> &all_tracks =
track_manager->getAllTrackIdentifiers();
std::vector<std::string> 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<std::string> all_tracks = getStringVector();
std::vector<std::string> 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

73
src/network/event.cpp Normal file
View File

@ -0,0 +1,73 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "event.hpp"
#include "network_manager.hpp"
#include <vector>
#include <stdio.h>
Event::Event(ENetEvent* event)
{
switch (event->type)
{
case ENET_EVENT_TYPE_CONNECT:
type = EVENT_TYPE_CONNECTED;
break;
case ENET_EVENT_TYPE_DISCONNECT:
type = EVENT_TYPE_DISCONNECTED;
break;
case ENET_EVENT_TYPE_RECEIVE:
type = EVENT_TYPE_MESSAGE;
break;
default:
break;
}
if (type == EVENT_TYPE_MESSAGE)
data = std::string((char*)(event->packet->data));
else if (event->data)
data = std::string((char*)(event->data));
if (event->packet)
m_packet = event->packet;
std::vector<STKPeer*> 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)
{
printf("The peer still does not exist in %lu peers\n", peers.size());
STKPeer* new_peer = new STKPeer();
new_peer->m_peer = event->peer;
peer = new_peer;
}
}
Event::~Event()
{
if (m_packet)
enet_packet_destroy(m_packet);
}

69
src/network/event.hpp Normal file
View File

@ -0,0 +1,69 @@
//
// 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 "stk_peer.hpp"
#include <stdint.h>
#include <string>
/*!
* \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();
EVENT_TYPE type; //!< Type of the event.
std::string data; //!< Copy of the data passed by the event.
STKPeer* peer; //!< Pointer to the peer that triggered that event.
private:
ENetPacket* m_packet; //!< A pointer on the ENetPacket to be deleted.
};
#endif // EVENT_HPP

View File

@ -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

View File

@ -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 "http_functions.hpp"
#include <iostream>
#include <string>
#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
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)
printf("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)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
return readBuffer;
}
void shutdown()
{
curl_easy_cleanup(curl);
curl_global_cleanup();
}
}

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -16,15 +16,20 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_KART_UPDATE_MESSAGE_HPP
#define HEADER_KART_UPDATE_MESSAGE_HPP
#ifndef HTTP_FUNCTIONS_HPP
#define HTTP_FUNCTIONS_HPP
#include "network/message.hpp"
#include <string>
class KartUpdateMessage : public Message
namespace HTTP
{
public:
KartUpdateMessage();
KartUpdateMessage(ENetPacket* pkt);
}; // KartUpdateMessage
#endif
void init();
void shutdown();
std::string getPage(std::string url);
}
#endif // HTTP_FUNCTIONS_HPP

View File

@ -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

View File

@ -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; i<num_local_players; i++)
{
const AbstractKart *kart = world->getLocalPlayerKart(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; i<kart_id_offset+num_local_players; i++)
{
KartControl kc(this);
AbstractKart *kart = World::getWorld()->getKart(i);
if(kart->getController()->isNetworkController())
{
((NetworkKart*)kart)->setControl(kc);
}
}
}; // KartControlMessage

View File

@ -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; i<num_karts; i++)
{
const AbstractKart* kart = world->getKart(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; i<num_karts; i++)
{
// Currently not used
KartControl kc(this);
Vec3 xyz = getVec3();
btQuaternion q = getQuaternion();
AbstractKart *kart = world->getKart(i);
kart->setXYZ(xyz);
kart->setRotation(q);
} // for i
}; // KartUpdateMessage

View File

@ -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 <string>
#include <math.h>
#include <stdexcept>
#include <assert.h>
/** 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<std::string>
*/
int Message::getStringVectorLength(const std::vector<std::string>& vs)
{
int len=getShortLength();
for(unsigned int i=0; i<vs.size(); i++)
len += getStringLength(vs[i]);
return len;
} // getStringVectorLength
// ----------------------------------------------------------------------------
/** Adds a std::vector<std::string> to the message.
*/
void Message::addStringVector(const std::vector<std::string>& vs)
{
assert(vs.size()<32767);
addShort(vs.size());
for(unsigned short i=0; i<vs.size(); i++)
addString(vs[i]);
} // addStringVector
// ----------------------------------------------------------------------------
std::vector<std::string> Message::getStringVector()
{
std::vector<std::string> vs;
vs.resize(getShort());
for(unsigned int i=0; i<vs.size(); i++)
vs[i]=getString();
return vs;
} // getStringVector
// ----------------------------------------------------------------------------

View File

@ -1,143 +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.
#ifndef HEADER_MESSAGE_HPP
#define HEADER_MESSAGE_HPP
#include <cstring>
#include <string>
#include <vector>
#include <assert.h>
#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<std::string>& 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<n; i++)
addInt(d[i]); }
void addVec3(const Vec3& v) { addFloat(v.getX());
addFloat(v.getY());
addFloat(v.getZ()); }
void addQuaternion(const btQuaternion& q) { addFloat(q.getX());
addFloat(q.getY());
addFloat(q.getZ());
addFloat(q.getW()); }
int getInt();
bool getBool() { return getChar()==1; }
short getShort();
float getFloat();
std::string getString();
std::vector<std::string>
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<std::string>& 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

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -16,16 +16,13 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_KART_CONTROL_MESSAGE_HPP
#define HEADER_KART_CONTROL_MESSAGE_HPP
#include "network_interface.hpp"
#include "network/message.hpp"
class KartControlMessage : public Message
NetworkInterface::NetworkInterface()
{
public:
KartControlMessage();
KartControlMessage(ENetPacket* pkt, int kart_id_offset,
int num_local_players);
}; // KartUpdateMessage
#endif
}
NetworkInterface::~NetworkInterface()
{
}

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -16,25 +16,30 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_RACE_START_MESSAGE_HPP
#define HEADER_RACE_START_MESSAGE_HPP
#ifndef NETWORK_INTERFACE_H
#define NETWORK_INTERFACE_H
#include "network/message.hpp"
#include "network/remote_kart_info.hpp"
#include "race/race_manager.hpp"
#include "singleton.hpp"
#include "types.hpp"
#include "network_manager.hpp"
class RaceStartMessage : public Message
#include <stdint.h>
#include <pthread.h>
#include <string>
class NetworkInterface : public Singleton<NetworkInterface>
{
private:
// For now this is an empty message
public:
RaceStartMessage() : Message(Message::MT_RACE_START)
{
allocate(0);
} // RaceStartMessage
friend class Singleton<NetworkInterface>;
public:
void initNetwork(bool server);
protected:
// protected functions
NetworkInterface();
virtual ~NetworkInterface();
};
RaceStartMessage(ENetPacket* pkt):Message(pkt, MT_RACE_START)
{
}
}; // RaceStartMessage
#endif
#endif // NETWORK_INTERFACE_H

View File

@ -1,43 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2005 Steve Baker <sjbaker1@airmail.net>
// 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

View File

@ -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,725 +16,112 @@
// 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_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 "protocols/hide_public_address.hpp"
#include "protocols/show_public_address.hpp"
#include "protocols/get_public_address.hpp"
#include "protocol_manager.hpp"
#include "client_network_manager.hpp"
#include "server_network_manager.hpp"
#include <stdio.h>
void* protocolManagerUpdate(void* data)
{
ProtocolManager* manager = static_cast<ProtocolManager*>(data);
while(1)
{
manager->update();
}
return NULL;
}
NetworkManager* network_manager = 0;
NetworkManager::NetworkManager()
{
m_mode = NW_NONE;
m_state = NS_ACCEPT_CONNECTIONS;
m_host = NULL;
m_public_address.ip = 0;
m_public_address.port = 0;
m_protocol_manager_update_thread = NULL;
}
m_num_clients = 0;
m_host_id = 0;
if (enet_initialize () != 0)
{
fprintf (stderr, "An error occurred while initializing ENet.\n");
exit(-1);
}
} // NetworkManager
// -----------------------------------------------------------------------------
bool NetworkManager::initialiseConnections()
NetworkManager::~NetworkManager()
{
switch(m_mode)
{
case NW_NONE: return true;
case NW_CLIENT: return initClient();
case NW_SERVER: return initServer();
}
return true;
} // NetworkManager
}
// -----------------------------------------------------------------------------
NetworkManager::~NetworkManager()
void NetworkManager::run()
{
if(m_mode==NW_SERVER || m_mode==NW_CLIENT) enet_host_destroy(m_host);
enet_deinitialize();
} // ~NetworkManager
ProtocolManager::getInstance<ProtocolManager>();
m_protocol_manager_update_thread = (pthread_t*)(malloc(sizeof(pthread_t)));
pthread_create(m_protocol_manager_update_thread, NULL, protocolManagerUpdate, ProtocolManager::getInstance());
}
// -----------------------------------------------------------------------------
bool NetworkManager::initServer()
bool NetworkManager::connect(TransportAddress peer)
{
ENetAddress address;
address.host = ENET_HOST_ANY;
address.port = UserConfigParams::m_server_port;
if (peerExists(peer))
return isConnectedTo(peer);
return STKPeer::connectToHost(m_localhost, peer, 2, 0);
}
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)
{
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
m_client_names.push_back("server");
return true;
} // initServer
// -----------------------------------------------------------------------------
/** Initialises the client. This function tries to connect to the server.
*/
bool NetworkManager::initClient()
void NetworkManager::setManualSocketsMode(bool manual)
{
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()
{
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:
{
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<CharSel*>(menu_manager->getCurrentMenu());
if(menu)
menu->updateAvailableCharacters();
*/
// Broadcast the information about a selected kart to all clients
CharacterConfirmMessage ccm(ki.getKartName(), hostid);
broadcastToClients(ccm);
// See if this was the last message, i.e. we have received at least
// one message from each client, and the size of the kart_info
// array is the same as the number of all players (which does not
// yet include the number of players on the host).
if(m_barrier_count == (int)m_num_clients &&
m_num_all_players==(int)m_kart_info.size())
{
// we can't send the race info yet, since the server might
// not yet have selected all characters!
m_state = NS_ALL_REMOTE_CHARACTERS_DONE;
}
break;
}
case NS_READY_SET_GO_BARRIER:
{
m_barrier_count ++;
if(m_barrier_count==(int)m_num_clients)
{
m_state = NS_RACING;
RaceStartMessage m;
broadcastToClients(m);
}
break;
}
case NS_RACE_RESULT_BARRIER:
{
// Other message, esp. kart control, are silently ignored.
// FIXME: we might want to make sure that no such message actually arrives
if(Message::peekType(event->packet)!=Message::MT_RACE_RESULT_ACK)
{
enet_packet_destroy(event->packet);
return;
}
m_barrier_count++;
if(m_barrier_count==(int)m_num_clients)
{
m_state = NS_MAIN_MENU;
}
break;
}
default: assert(0); // should not happen
} // switch m_state
} // handleMessageAtServer
// ----------------------------------------------------------------------------
void NetworkManager::handleMessageAtClient(ENetEvent *event)
{ // handle message at client (from server)
switch(m_state)
{
case NS_WAIT_FOR_AVAILABLE_CHARACTERS:
{
CharacterInfoMessage m(event->packet);
// FIXME: handle list of available characters
m_state = NS_CHARACTER_SELECT;
break;
}
case NS_CHARACTER_SELECT:
{
CharacterConfirmMessage m(event->packet);
kart_properties_manager->selectKartName(m.getKartName());
// TODO - karts selection screen in networking
/*
CharSel *menu = dynamic_cast<CharSel*>(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<CharSel*>(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<RaceResultsGUI*>(menu_manager->getCurrentMenu());
if(menu)
menu->setSelectedWidget(message.getSelectedMenu());*/
m_state = NS_RACE_RESULT_BARRIER_OVER;
break;
}
default:
{
printf("received unknown message: type %d\n",
Message::peekType(event->packet));
// assert(0); // should not happen
}
} // switch m_state
} // handleMessageAtClient
// ----------------------------------------------------------------------------
void NetworkManager::update(float dt)
{
if(m_mode==NW_NONE) return;
// Messages during racing are handled in the sendUpdates/receiveUpdate
// calls, so don't do anything in this case.
if(m_state==NS_RACING) return;
ENetEvent event;
int result = enet_host_service (m_host, &event, 0);
if(result==0) return;
if(result<0)
{
fprintf(stderr, "Error while receiving messages -> ignored.\n");
return;
}
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT: handleNewConnection(&event); break;
case ENET_EVENT_TYPE_RECEIVE:
if(m_mode==NW_SERVER)
handleMessageAtServer(&event);
else
handleMessageAtClient(&event);
break;
case ENET_EVENT_TYPE_DISCONNECT: handleDisconnection(&event); break;
case ENET_EVENT_TYPE_NONE: break;
}
} // update
// ----------------------------------------------------------------------------
void NetworkManager::broadcastToClients(Message &m)
{
enet_host_broadcast(m_host, 0, m.getPacket());
enet_host_flush(m_host);
} // broadcastToClients
// ----------------------------------------------------------------------------
void NetworkManager::sendToServer(Message &m)
{
enet_peer_send(m_server, 0, m.getPacket());
enet_host_flush(m_host);
} // sendToServer
// ----------------------------------------------------------------------------
/** Cleans up character related data structures. Must be called before any
* character related data is set.
*/
void NetworkManager::initCharacterDataStructures()
{
// This is called the first time the character selection menu is displayed
if(m_mode==NW_CLIENT)
{
// Change state to wait for list of characters from server
m_state = NS_WAIT_FOR_AVAILABLE_CHARACTERS;
}
else // Server or no network
{
if(m_mode==NW_SERVER)
{
// server: create message with all valid characters
// ================================================
for(unsigned int i=1; i<=m_num_clients; i++)
{
CharacterInfoMessage m(i);
enet_peer_send(m_clients[i], 0, m.getPacket());
}
enet_host_flush(m_host);
}
// For server and no network:
// ==========================
// Prepare the data structures to receive and
// store information from all clients.
m_num_local_players.clear();
// Server (hostid 0) is not included in the num_clients count. So to
// be able to use the hostid as index, we have to allocate one
// additional element.
m_num_local_players.resize(m_num_clients+1, -1);
m_num_local_players[0] = race_manager->getNumLocalPlayers();
m_kart_info.clear();
m_num_all_players = 0;
// use barrier count to see if we had at least one message from each host
m_barrier_count = 0;
m_state = NS_CHARACTER_SELECT;
}
} // switchTocharacterSelection
// ----------------------------------------------------------------------------
/** Called on the client to send the data about the selected kart to the
* server and wait for confirmation.
* \param player_id Local id of the player which selected the kart.
* \param kart_id Identifier of the selected kart. this is used to wait till
* a message about this kart is received back from the server.
*/
void NetworkManager::sendCharacterSelected(int player_id,
const std::string &kart_id)
{
if(m_mode==NW_SERVER)
{
CharacterConfirmMessage ccm(kart_id, getMyHostId());
broadcastToClients(ccm);
}
else if(m_mode==NW_CLIENT)
{
CharacterSelectedMessage m(player_id);
sendToServer(m);
// Wait till we receive confirmation about the selected character.
m_state = NS_WAIT_FOR_KART_CONFIRMATION;
m_kart_to_confirm = kart_id;
}
} // sendCharacterSelected
// ----------------------------------------------------------------------------
void NetworkManager::waitForRaceInformation()
{
m_state = NS_WAIT_FOR_RACE_DATA;
} // waitForRaceInformation
// ----------------------------------------------------------------------------
void NetworkManager::worldLoaded()
{
if(m_mode==NW_CLIENT)
{
WorldLoadedMessage m;
sendToServer(m);
m_state = NS_READY_SET_GO_BARRIER;
}
} // worldLoaded
// ----------------------------------------------------------------------------
/** Receive and store the information from sendKartsInformation()
*/
void NetworkManager::setupPlayerKartInfo()
{
// Not sure if this should be here, but without it extra uncontrolled
// human players accumulate after each race.
m_kart_info.clear();
// Get the local kart info
for(unsigned int i=0; i<race_manager->getNumLocalPlayers(); 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; i<m_kart_info.size(); i++)
{
m_kart_info[i].setGlobalPlayerId(i);
race_manager->setPlayerKart(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; i<num_messages; i++)
{
int result = enet_host_service (m_host, &event, 0);
if(result<0)
{
fprintf(stderr, m_mode==NW_SERVER
? "Error while waiting for client control - chaos will reign.\n"
: "Error while waiting for server update - chaos will reign.\n");
correct=false;
continue;
}
// if no message, busy wait
if(result==0 || event.type==ENET_EVENT_TYPE_NONE)
{
i--;
continue;
}
if(event.type!=ENET_EVENT_TYPE_RECEIVE)
{
fprintf(stderr, "unexpected message, ignored.\n");
i--;
continue;
}
if(m_mode==NW_SERVER)
{
int host_id = getHostId(event.peer);
KartControlMessage(event.packet, host_id, m_num_local_players[host_id]);
}
else
{
// Test if it is a game over message:
if(Message::peekType(event.packet)==Message::MT_RACE_RESULT)
{
RaceResultMessage m(event.packet);
m_state = NS_WAIT_FOR_RACE_RESULT;
World::getWorld()->enterRaceOverState();
return;
}
race_state->receive(event.packet);
}
} // for i<num_messages
if(!correct)
fprintf(stderr, "Missing messages need to be handled!\n");
} // receiveUpdates
// ----------------------------------------------------------------------------
void NetworkManager::waitForClientData()
{
ENetEvent event;
bool correct=true;
for(unsigned int i=1; i<=m_num_clients; i++)
{
int result = enet_host_service (m_host, &event, 100);
if(result<=0)
{
fprintf(stderr, "Error while waiting for client control - chaos will reign.\n");
correct=false;
continue;
}
if(event.type!=ENET_EVENT_TYPE_RECEIVE)
{
fprintf(stderr, "received no message - chaos will reign.\n");
correct=false;
continue;
}
int host_id = getHostId(event.peer);
KartControlMessage(event.packet, host_id, m_num_local_players[host_id]);
}
if(!correct)
fprintf(stderr, "Missing messages need to be handled!\n");
} // 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()
{
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);
}
if (manual)
m_localhost->stopListening();
else
m_localhost->startListening();
}
void NetworkManager::notifyEvent(Event* event)
{
printf("EVENT received\n");
switch (event->type)
{
broadcastToClients(m);
case EVENT_TYPE_MESSAGE:
printf("Message, Sender : %u, message = \"%s\"\n", event->peer->getAddress(), event->data.c_str());
break;
case EVENT_TYPE_DISCONNECTED:
printf("Somebody is now disconnected. There are now %lu peers.\n", m_peers.size());
printf("Disconnected host: %i.%i.%i.%i:%i\n", event->peer->getAddress()>>24&0xff, event->peer->getAddress()>>16&0xff, event->peer->getAddress()>>8&0xff, event->peer->getAddress()&0xff,event->peer->getPort());
// remove the peer:
for (unsigned int i = 0; i < m_peers.size(); i++)
{
if (m_peers[i] == event->peer)
{
delete m_peers[i];
m_peers.erase(m_peers.begin()+i, m_peers.begin()+i+1);
break;
}
}
printf("ERROR : the peer that has been disconnected was not registered by the Network Manager.\n");
break;
case EVENT_TYPE_CONNECTED:
printf("A client has just connected. There are now %lu peers.\n", m_peers.size() + 1);
// create the new peer:
m_peers.push_back(event->peer);
break;
}
} // sendRaceResultAck
ProtocolManager::getInstance()->notifyEvent(event);
}
void NetworkManager::setLogin(std::string username, std::string password)
{
m_player_login.username = username;
m_player_login.password = password;
}
void NetworkManager::setPublicAddress(TransportAddress addr)
{
m_public_address = addr;
}
bool NetworkManager::peerExists(TransportAddress peer)
{
return m_localhost->peerExists(peer);
}
bool NetworkManager::isConnectedTo(TransportAddress peer)
{
return m_localhost->isConnectedTo(peer);
}

View File

@ -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,57 @@
// 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 <string>
#include "stk_peer.hpp"
#include "stk_host.hpp"
#include <vector>
#include "enet/enet.h"
#include "protocol_manager.hpp"
#include "singleton.hpp"
#include "types.hpp"
#include "event.hpp"
#include "network/remote_kart_info.hpp"
class Message;
class NetworkManager
class NetworkManager : public Singleton<NetworkManager>
{
public:
// The mode the network manager is operating in
enum NetworkMode {NW_SERVER, NW_CLIENT, NW_NONE};
friend class Singleton<NetworkManager>;
public:
virtual void run();
// network management functions
virtual bool connect(TransportAddress peer);
virtual void setManualSocketsMode(bool manual);
virtual void notifyEvent(Event* event);
virtual void packetReceived(char* data) = 0;
// States for the finite state machine. First for server:
enum NetworkState {NS_MAIN_MENU, // before char sel gui
NS_ACCEPT_CONNECTIONS, // server: accept connections
NS_WAIT_FOR_AVAILABLE_CHARACTERS, // client: wait for list
NS_ALL_REMOTE_CHARACTERS_DONE, // server: all client data received
NS_WAIT_FOR_KART_CONFIRMATION, // client: wait for confirmation
// if character selection was ok
NS_KART_CONFIRMED, // Character was confirmed
NS_WAIT_FOR_RACE_DATA, // client: wait for race info
NS_READY_SET_GO_BARRIER, // c&s: barrier before r.s.g.
NS_CHARACTER_SELECT, // c&s: character select in progress
NS_LOADING_WORLD, // client: loading world
NS_RACING,
NS_WAIT_FOR_RACE_RESULT, // clients: waiting for race results
NS_RACE_RESULT_BARRIER , // Wait till all ack results
NS_RACE_RESULT_BARRIER_OVER // Barrier is over, goto next state
};
private:
NetworkMode m_mode;
NetworkState m_state;
unsigned int m_num_clients;
std::vector<RemoteKartInfo> m_kart_info;
int m_host_id;
std::vector<std::string> m_client_names;
std::vector<int> m_num_local_players;
std::vector<int> 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<ENetPeer*> 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<STKPeer*> getPeers() { return m_peers; }
protected:
NetworkManager();
virtual ~NetworkManager();
// protected members
std::vector<STKPeer*> m_peers;
STKHost* m_localhost;
bool m_playing_online;
TransportAddress m_public_address;
PlayerLogin m_player_login;
pthread_t* m_protocol_manager_update_thread;
};
extern NetworkManager *network_manager;
#endif
#endif // NETWORKMANAGER_HPP

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -16,22 +16,34 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_CONNECT_MESSAGE_HPP
#define HEADER_CONNECT_MESSAGE_HPP
#include "protocol.hpp"
#include <string>
#include "network/message.hpp"
class ConnectMessage : public Message
Protocol::Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type)
{
private:
std::string m_id;
void setId();
public:
ConnectMessage();
ConnectMessage(ENetPacket* pkt);
const std::string&
getId() { return m_id; }
}; // ConnectMessage
#endif
m_callback_object = callback_object;
m_type = type;
}
Protocol::~Protocol()
{
}
void Protocol::pause()
{
m_listener->requestPause(this);
}
void Protocol::unpause()
{
m_listener->requestUnpause(this);
}
void Protocol::setListener(ProtocolManager* listener)
{
m_listener = listener;
}
PROTOCOL_TYPE Protocol::getProtocolType()
{
return m_type;
}

105
src/network/protocol.hpp Normal file
View File

@ -0,0 +1,105 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef PROTOCOL_HPP
#define PROTOCOL_HPP
#include "protocol_manager.hpp"
#include "types.hpp"
#include <stdint.h>
/** \enum PROTOCOL_TYPE
* \brief The types that protocols can have. This is used to select which protocol receives which event.
* \ingroup network
*/
enum PROTOCOL_TYPE
{
PROTOCOL_NONE = 0, //!< No protocol type assigned.
PROTOCOL_CONNECTION = 1, //!< Protocol that deals with client-server connection.
PROTOCOL_LOBBY_ROOM = 2, //!< Protocol that is used during the lobby room phase.
PROTOCOL_SILENT = 0xffff //!< Used for protocols that do not subscribe to any network event.
};
/** \class Protocol
* \brief Abstract class used to define the global protocol functions.
* A protocol is an entity that is started at a point, and that is updated by a thread.
* A protocol can be terminated by an other class, or it can terminate itself if has fulfilled its role.
* This class must be inherited to make any network job.
* \ingroup network
*/
class Protocol
{
public:
/*!
* \brief Constructor
*
* Sets the basic protocol parameters, as the callback object and the protocol type.
*
* \param callback_object The callback object that will be used by the protocol. Protocols that do not use callback objects must set it to NULL.
* \param type The type of the protocol.
*/
Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type);
/*!
* \brief Destructor
*/
virtual ~Protocol();
/*!
* \brief Notify a protocol matching the Event type of that event.
* \param event : Pointer to the event.
*/
virtual void notifyEvent(Event* event) = 0;
/*!
* \brief Set the protocol listener.
* \param listener : Pointer to the listener.
*/
void setListener(ProtocolManager* listener);
/*!
* \brief Called when the protocol is going to start. Must be re-defined by subclasses.
*/
virtual void setup() = 0;
/*!
* \brief Called when the protocol is paused (by an other entity or by itself).
* This function must be called by the subclasse's pause function if re-defined.
*/
virtual void pause();
/*!
* \brief Called when the protocol is unpaused.
* This function must be called by the subclasse's unpause function if re-defined.
*/
virtual void unpause();
/*!
* \brief Called by the protocol listener as often as possible. Must be re-defined.
*/
virtual void update() = 0;
/*!
* \brief Method to get a protocol's type.
* \return The protocol type.
*/
PROTOCOL_TYPE getProtocolType();
protected:
ProtocolManager* m_listener; //!< The protocol listener
PROTOCOL_TYPE m_type; //!< The type of the protocol
CallbackObject* m_callback_object; //!< The callback object, if needed
};
#endif // PROTOCOL_HPP

View File

@ -0,0 +1,287 @@
//
// 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 "protocol_manager.hpp"
#include "protocol.hpp"
#include <assert.h>
#include <stdio.h>
#include <cstdlib>
#define RAND_MAX 65536
ProtocolManager::ProtocolManager()
{
pthread_mutex_init(&m_events_mutex, NULL);
pthread_mutex_init(&m_protocols_mutex, NULL);
pthread_mutex_init(&m_requests_mutex, NULL);
pthread_mutex_init(&m_id_mutex, NULL);
m_next_protocol_id = 0;
}
ProtocolManager::~ProtocolManager()
{
}
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(std::string message)
{
std::string newMessage = " " + message; // add one byte
newMessage[0] = (char)(0);
}
int ProtocolManager::requestStart(Protocol* protocol)
{
// create the request
ProtocolRequest req;
ProtocolInfo info;
info.protocol = protocol;
info.state = PROTOCOL_STATE_RUNNING;
assignProtocolId(&info); // assign a unique id to the protocol.
req.protocol_info = info;
req.type = PROTOCOL_REQUEST_START;
// add it to the request stack
pthread_mutex_lock(&m_requests_mutex);
m_requests.push_back(req);
pthread_mutex_unlock(&m_requests_mutex);
return info.id;
}
void ProtocolManager::requestStop(Protocol* protocol)
{
// create the request
ProtocolRequest req;
req.protocol_info.protocol = protocol;
req.type = PROTOCOL_REQUEST_STOP;
// add it to the request stack
pthread_mutex_lock(&m_requests_mutex);
m_requests.push_back(req);
pthread_mutex_unlock(&m_requests_mutex);
}
void ProtocolManager::requestPause(Protocol* protocol)
{
// create the request
ProtocolRequest req;
req.protocol_info.protocol = protocol;
req.type = PROTOCOL_REQUEST_PAUSE;
// add it to the request stack
pthread_mutex_lock(&m_requests_mutex);
m_requests.push_back(req);
pthread_mutex_unlock(&m_requests_mutex);
}
void ProtocolManager::requestUnpause(Protocol* protocol)
{
// create the request
ProtocolRequest req;
req.protocol_info.protocol = protocol;
req.type = PROTOCOL_REQUEST_UNPAUSE;
// add it to the request stack
pthread_mutex_lock(&m_requests_mutex);
m_requests.push_back(req);
pthread_mutex_unlock(&m_requests_mutex);
}
void ProtocolManager::requestTerminate(Protocol* protocol)
{
// create the request
ProtocolRequest req;
req.protocol_info.protocol = protocol;
req.type = PROTOCOL_REQUEST_TERMINATE;
// add it to the request stack
pthread_mutex_lock(&m_requests_mutex);
m_requests.push_back(req);
pthread_mutex_unlock(&m_requests_mutex);
}
void ProtocolManager::startProtocol(ProtocolInfo protocol)
{
printf("__ProtocolManager> A new protocol with id=%u has been started. There are %ld protocols running.\n", protocol.id, m_protocols.size()+1);
// add the protocol to the protocol vector so that it's updated
pthread_mutex_lock(&m_protocols_mutex);
m_protocols.push_back(protocol);
pthread_mutex_unlock(&m_protocols_mutex);
// setup the protocol and notify it that it's started
protocol.protocol->setListener(this);
protocol.protocol->setup();
}
void ProtocolManager::stopProtocol(ProtocolInfo protocol)
{
}
void ProtocolManager::pauseProtocol(ProtocolInfo protocol)
{
for (unsigned int i = 0; i < m_protocols.size(); i++)
{
if (m_protocols[i].protocol == protocol.protocol && m_protocols[i].state == PROTOCOL_STATE_RUNNING)
{
m_protocols[i].state = PROTOCOL_STATE_PAUSED;
m_protocols[i].protocol->pause();
}
}
}
void ProtocolManager::unpauseProtocol(ProtocolInfo protocol)
{
for (unsigned int i = 0; i < m_protocols.size(); i++)
{
if (m_protocols[i].protocol == protocol.protocol && m_protocols[i].state == PROTOCOL_STATE_PAUSED)
{
m_protocols[i].state = PROTOCOL_STATE_RUNNING;
m_protocols[i].protocol->unpause();
}
}
}
void ProtocolManager::protocolTerminated(ProtocolInfo protocol)
{
pthread_mutex_lock(&m_protocols_mutex); // be sure that noone accesses the protocols vector while we erase a protocol
int offset = 0;
for (unsigned int i = 0; i < m_protocols.size(); i++)
{
if (m_protocols[i-offset].protocol == protocol.protocol)
{
delete m_protocols[i].protocol;
m_protocols.erase(m_protocols.begin()+(i-offset), m_protocols.begin()+(i-offset)+1);
offset++;
}
}
printf("__ProtocolManager> A protocol has been terminated. There are %ld protocols running.\n", m_protocols.size());
pthread_mutex_unlock(&m_protocols_mutex);
}
void ProtocolManager::update()
{
// before updating, notice protocols that they have received information
pthread_mutex_lock(&m_events_mutex); // secure threads
int size = m_events_to_process.size();
for (int i = 0; i < size; i++)
{
Event* event = m_events_to_process.back();
PROTOCOL_TYPE searchedProtocol = PROTOCOL_NONE;
if (event->data.size() > 0)
searchedProtocol = (PROTOCOL_TYPE)(event->data[0]);
for (unsigned int i = 0; i < m_protocols.size() ; i++)
{
if (m_protocols[i].protocol->getProtocolType() == searchedProtocol || event->type != EVENT_TYPE_MESSAGE) // pass data to protocols even when paused
m_protocols[i].protocol->notifyEvent(event);
}
delete event;
m_events_to_process.pop_back();
}
pthread_mutex_unlock(&m_events_mutex); // release the mutex
// now update all protocols
pthread_mutex_lock(&m_protocols_mutex);
for (unsigned int i = 0; i < m_protocols.size(); i++)
{
if (m_protocols[i].state == PROTOCOL_STATE_RUNNING)
m_protocols[i].protocol->update();
}
pthread_mutex_unlock(&m_protocols_mutex);
// process queued events for protocols
pthread_mutex_lock(&m_requests_mutex);
for (unsigned int i = 0; i < m_requests.size(); i++)
{
switch (m_requests[i].type)
{
case PROTOCOL_REQUEST_START:
startProtocol(m_requests[i].protocol_info);
break;
case PROTOCOL_REQUEST_STOP:
stopProtocol(m_requests[i].protocol_info);
break;
case PROTOCOL_REQUEST_PAUSE:
pauseProtocol(m_requests[i].protocol_info);
break;
case PROTOCOL_REQUEST_UNPAUSE:
unpauseProtocol(m_requests[i].protocol_info);
break;
case PROTOCOL_REQUEST_TERMINATE:
protocolTerminated(m_requests[i].protocol_info);
break;
}
}
m_requests.clear();
pthread_mutex_unlock(&m_requests_mutex);
}
int ProtocolManager::runningProtocolsCount()
{
return m_protocols.size();
}
PROTOCOL_STATE ProtocolManager::getProtocolState(uint32_t id)
{
for (unsigned int i = 0; i < m_protocols.size(); i++)
{
if (m_protocols[i].id == id) // we know a protocol with that id
return m_protocols[i].state; // return its state
}
// the protocol isn't running right now
for (unsigned int i = 0; i < m_requests.size(); i++)
{
if (m_requests[i].protocol_info.id == id) // the protocol is going to be started
return PROTOCOL_STATE_RUNNING; // we can say it's running
}
return PROTOCOL_STATE_TERMINATED; // else, it's already finished
}
PROTOCOL_STATE ProtocolManager::getProtocolState(Protocol* protocol)
{
for (unsigned int i = 0; i < m_protocols.size(); i++)
{
if (m_protocols[i].protocol == protocol) // the protocol is known
return m_protocols[i].state; // return its state
}
for (unsigned int i = 0; i < m_requests.size(); i++)
{
if (m_requests[i].protocol_info.protocol == protocol) // the protocol is going to be started
return PROTOCOL_STATE_RUNNING; // we can say it's running
}
return PROTOCOL_STATE_TERMINATED; // we don't know this protocol at all, it's finished
}
int ProtocolManager::getProtocolID(Protocol* protocol)
{
for (unsigned int i = 0; i < m_protocols.size(); i++)
{
if (m_protocols[i].protocol == protocol)
return m_protocols[i].id;
}
return 0;
}
void ProtocolManager::assignProtocolId(ProtocolInfo* protocol_info)
{
pthread_mutex_lock(&m_id_mutex);
protocol_info->id = m_next_protocol_id;
m_next_protocol_id++;
pthread_mutex_unlock(&m_id_mutex);
}

View File

@ -0,0 +1,266 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/*! \file protocol_manager.hpp
* \brief Contains structures and enumerations related to protocol management.
*/
#ifndef PROTOCOL_MANAGER_HPP
#define PROTOCOL_MANAGER_HPP
#include "singleton.hpp"
#include "event.hpp"
#include <vector>
#include <stdint.h>
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<ProtocolManager>
{
friend class Singleton<ProtocolManager>;
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(std::string message);
/*!
* \brief Asks the manager to start a protocol.
* This function will store the request, and process it at a time it is
* thread-safe.
* \param protocol : A pointer to the protocol to start
* \return The unique id of the protocol that is being started.
*/
virtual int requestStart(Protocol* protocol);
/*!
* \brief Asks the manager to stop a protocol.
* This function will store the request, and process it at a time it is
* thread-safe.
* \param protocol : A pointer to the protocol to stop
*/
virtual void requestStop(Protocol* protocol);
/*!
* \brief Asks the manager to pause a protocol.
* This function will store the request, and process it at a time it is
* thread-safe.
* \param protocol : A pointer to the protocol to pause
*/
virtual void requestPause(Protocol* protocol);
/*!
* \brief Asks the manager to unpause a protocol.
* This function will store the request, and process it at a time it is
* thread-safe.
* \param protocol : A pointer to the protocol to unpause
*/
virtual void requestUnpause(Protocol* protocol);
/*!
* \brief Notifies the manager that a protocol is terminated.
* This function will store the request, and process it at a time it is
* thread-safe.
* \param protocol : A pointer to the protocol that is finished
*/
virtual void requestTerminate(Protocol* protocol);
/*!
* \brief Updates the manager.
*
* This function processes the events queue, notifies the concerned
* protocols that they have events to process. Then ask all protocols
* to update themselves. Finally processes stored requests about
* starting, stoping, pausing etc... protocols.
* This function is called by a thread as often as possible.
* This function is not FPS-dependant.
*/
virtual void update();
/*!
* \brief Get the number of protocols running.
* \return The number of protocols that are actually running.
*/
virtual int runningProtocolsCount();
/*!
* \brief Get the state of a protocol using its id.
* \param id : The id of the protocol you seek the state.
* \return The state of the protocol.
*/
virtual PROTOCOL_STATE getProtocolState(uint32_t id);
/*!
* \brief Get the state of a protocol using a pointer on it.
* \param protocol : A pointer to the protocol you seek the state.
* \return The state of the protocol.
*/
virtual PROTOCOL_STATE getProtocolState(Protocol* protocol);
/*!
* \brief Get the id of a protocol.
* \param protocol : A pointer to the protocol you seek the id.
* \return The id of the protocol pointed by the protocol parameter.
*/
virtual int getProtocolID(Protocol* protocol);
protected:
// protected functions
/*!
* \brief Constructor
*/
ProtocolManager();
/*!
* \brief Destructor
*/
virtual ~ProtocolManager();
/*!
* \brief Assign an id to a protocol.
* This function will assign m_next_protocol_id as the protocol id.
* This id starts at 0 at the beginning and is increased by 1 each time
* a protocol starts.
* \param protocol_info : The protocol info that needs an id.
*/
void assignProtocolId(ProtocolInfo* protocol_info);
/*!
* \brief Starts a protocol.
* Add the protocol info to the m_protocols vector.
* \param protocol : ProtocolInfo to start.
*/
virtual void startProtocol(ProtocolInfo protocol);
/*!
* \brief Stops a protocol.
* Coes nothing. Noone can stop running protocols for now.
* \param protocol : ProtocolInfo to stop.
*/
virtual void stopProtocol(ProtocolInfo protocol);
/*!
* \brief Pauses a protocol.
* Pauses a protocol and tells it that it's being paused.
* \param protocol : ProtocolInfo to pause.
*/
virtual void pauseProtocol(ProtocolInfo protocol);
/*!
* \brief Unpauses a protocol.
* Unpauses a protocol and notifies it.
* \param protocol : ProtocolInfo to unpause.
*/
virtual void unpauseProtocol(ProtocolInfo protocol);
/*!
* \brief Notes that a protocol is terminated.
* Remove a protocol from the protocols vector.
* \param protocol : ProtocolInfo concerned.
*/
virtual void protocolTerminated(ProtocolInfo protocol);
// protected members
/*!
* \brief Contains the running protocols.
* This stores the protocols that are either running or paused, their
* state and their unique id.
*/
std::vector<ProtocolInfo> m_protocols;
/*!
* \brief Contains the network events to pass to protocols.
*/
std::vector<Event*> m_events_to_process;
/*!
* \brief Contains the requests to start/stop etc... protocols.
*/
std::vector<ProtocolRequest> m_requests;
/*! \brief The next id to assign to a protocol.
* This value is incremented by 1 each time a protocol is started.
* If a protocol has an id lower than this value, it means that it have
* been formerly started.
*/
unsigned int m_next_protocol_id;
// mutexes:
/*! Used to ensure that the event queue is used thread-safely. */
pthread_mutex_t m_events_mutex;
/*! Used to ensure that the protocol vector is used thread-safely. */
pthread_mutex_t m_protocols_mutex;
/*! Used to ensure that the request vector is used thread-safely. */
pthread_mutex_t m_requests_mutex;
/*! Used to ensure that the protocol id is used in a thread-safe way.*/
pthread_mutex_t m_id_mutex;
};
#endif // PROTOCOL_MANAGER_HPP

View File

@ -0,0 +1,110 @@
//
// 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/time.hpp"
#include <stdio.h>
#include <stdlib.h>
// ----------------------------------------------------------------------------
ConnectToServer::ConnectToServer(CallbackObject* callback_object) :
Protocol(callback_object, PROTOCOL_CONNECTION)
{
m_server_ip = 0;
m_server_port = 0;
m_state = NONE;
}
// ----------------------------------------------------------------------------
ConnectToServer::~ConnectToServer()
{
}
// ----------------------------------------------------------------------------
void ConnectToServer::notifyEvent(Event* event)
{
if (event->type == EVENT_TYPE_CONNECTED &&
event->peer->getAddress() == m_server_ip &&
event->peer->getPort() == m_server_port)
{
printf("The Connect To Server protocol has received an event notifying \
that he's connected to the peer. The peer sent \"%s\"\n",
event->data.c_str());
m_state = DONE; // we received a message, we are connected
}
}
// ----------------------------------------------------------------------------
void ConnectToServer::setup()
{
m_state = NONE;
if (m_server_ip == 0 || m_server_port == 0 )
{
printf("You have to set the server's public ip:port of the server.\n");
m_listener->requestTerminate(this);
}
}
// ----------------------------------------------------------------------------
void ConnectToServer::update()
{
if (m_state == NONE)
{
static double target = 0;
double currentTime = Time::getSeconds();
// sometimes the getSeconds method forgets 3600 seconds.
while (currentTime < target-1800)
currentTime += 3600;
if (currentTime > target)
{
NetworkManager::getInstance()->connect(
TransportAddress(m_server_ip, m_server_port));
if (NetworkManager::getInstance()->isConnectedTo(
TransportAddress(m_server_ip, m_server_port)))
{
m_state = DONE;
return;
}
target = currentTime+5;
printf("Retrying to connect in 5 seconds.\n");
}
}
else if (m_state == DONE)
{
m_listener->requestTerminate(this);
}
}
// ----------------------------------------------------------------------------
void ConnectToServer::setServerAddress(uint32_t ip, uint16_t port)
{
m_server_ip = ip;
m_server_port = port;
}
// ----------------------------------------------------------------------------

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -16,27 +16,34 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_NUM_PLAYERS_MESSAGE_HPP
#define HEADER_NUM_PLAYERS_MESSAGE_HPP
#ifndef CONNECT_TO_SERVER_HPP
#define CONNECT_TO_SERVER_HPP
#include "network/protocol.hpp"
#include <string>
#include <sstream>
#ifndef WIN32
# include <unistd.h>
#endif
#include "network/message.hpp"
#include "race/race_manager.hpp"
class NumPlayersMessage : public Message
class ConnectToServer : public Protocol, public CallbackObject
{
private:
int m_num_players
public:
NumPlayersMessage():Message(Message::MT_CONNECT) { m_num_players=race }
NumPlayersMessage(ENetPacket* pkt):Message(pkt)
{ m_id=getString(); }
const std::string&
getNumPlayers() { return m_num_players; }
}; // ConnectMessage
#endif
public:
ConnectToServer(CallbackObject* callback_object);
virtual ~ConnectToServer();
virtual void notifyEvent(Event* event);
virtual void setup();
virtual void update();
void setServerAddress(uint32_t ip, uint16_t port);
protected:
uint32_t m_server_ip;
uint16_t m_server_port;
enum STATE
{
NONE,
DONE
};
STATE m_state;
};
#endif // CONNECT_TO_SERVER_HPP

View File

@ -0,0 +1,98 @@
//
// 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/time.hpp"
#include "network/http_functions.hpp"
#include <stdio.h>
#include <stdlib.h>
GetPeerAddress::GetPeerAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT)
{
}
GetPeerAddress::~GetPeerAddress()
{
}
void GetPeerAddress::notifyEvent(Event* event)
{
}
void GetPeerAddress::setup()
{
m_state = NONE;
}
void GetPeerAddress::update()
{
if (m_state == NONE)
{
static double target = 0;
double current_time = Time::getSeconds();
while (current_time < target-1800) // sometimes the getSeconds method forgets 3600 seconds.
current_time += 3600;
if (current_time > target)
{
char url[512];
sprintf(url, "http://stkconnect.freeserver.me/log.php?get&nick=%s", m_peer_name.c_str());
std::string result = HTTP::getPage(url);
if (result == "")
{
printf("__GetPeerAddress> The host you try to reach does not exist. Change the host name please.\n");
pause();
return;
}
std::string ip_addr = result;
ip_addr.erase(ip_addr.find_first_of(':'));
std::string port_nb = result;
port_nb.erase(0, port_nb.find_first_of(':')+1);
uint32_t dst_ip = (uint32_t)(atoi(ip_addr.c_str()));
uint16_t dst_port = (uint32_t)(atoi(port_nb.c_str()));
if (dst_ip == 0 || dst_port == 0)
{
printf("__GetPeerAddress> The host you try to reach is not online. There will be a new try in 10 seconds.\n");
target = current_time+10;
}
else
{
printf("__GetPeerAddress> Public ip of target is %i.%i.%i.%i:%i\n", (dst_ip>>24)&0xff, (dst_ip>>16)&0xff, (dst_ip>>8)&0xff, dst_ip&0xff, dst_port);
uint32_t server_ip = ((dst_ip&0x000000ff)<<24) // change the server IP to have a network-byte order
+ ((dst_ip&0x0000ff00)<<8)
+ ((dst_ip&0x00ff0000)>>8)
+ ((dst_ip&0xff000000)>>24);
uint16_t server_port = dst_port;
TransportAddress* addr = static_cast<TransportAddress*>(m_callback_object);
addr->ip = server_ip;
addr->port = server_port;
m_state = DONE;
}
}
}
else if (m_state == DONE)
{
m_listener->requestTerminate(this);
}
}
void GetPeerAddress::setPeerName(std::string peer_name)
{
m_peer_name = peer_name;
}

View File

@ -0,0 +1,47 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef GET_PEER_ADDRESS_HPP
#define GET_PEER_ADDRESS_HPP
#include "network/protocol.hpp"
class GetPeerAddress : public Protocol
{
public:
GetPeerAddress(CallbackObject* callback_object);
virtual ~GetPeerAddress();
virtual void notifyEvent(Event* event);
virtual void setup();
virtual void update();
void setPeerName(std::string peer_name);
protected:
std::string m_peer_name;
enum STATE
{
NONE,
DONE
};
STATE m_state;
};
#endif // GET_PEER_ADDRESS_HPP

View File

@ -0,0 +1,207 @@
//
// 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 <time.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
int stunRand()
{
static bool init = false;
if (!init)
{
srand(time(NULL));
init = true;
}
return rand();
}
GetPublicAddress::GetPublicAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT)
{
}
GetPublicAddress::~GetPublicAddress()
{
}
void GetPublicAddress::notifyEvent(Event* event)
{
}
void GetPublicAddress::setup()
{
m_state = NOTHING_DONE;
}
void GetPublicAddress::update()
{
if (m_state == NOTHING_DONE)
{
// format : 00MMMMMCMMMCMMMM (cf rfc 5389)
uint16_t message_type = 0b0000000000000001; // binding request
m_stun_tansaction_id[0] = stunRand();
m_stun_tansaction_id[1] = stunRand();
m_stun_tansaction_id[2] = stunRand();
uint16_t message_length = 0x0000;
uint8_t bytes[21]; // the message to be sent
// bytes 0-1 : the type of the message,
bytes[0] = (uint8_t)(message_type>>8);
bytes[1] = (uint8_t)(message_type);
// bytes 2-3 : message length added to header (attributes)
bytes[2] = (uint8_t)(message_length>>8);
bytes[3] = (uint8_t)(message_length);
// bytes 4-7 : magic cookie to recognize the stun protocol
bytes[4] = (uint8_t)(m_stun_magic_cookie>>24);
bytes[5] = (uint8_t)(m_stun_magic_cookie>>16);
bytes[6] = (uint8_t)(m_stun_magic_cookie>>8);
bytes[7] = (uint8_t)(m_stun_magic_cookie);
// bytes 8-19 : the transaction id
bytes[8] = (uint8_t)(m_stun_tansaction_id[0]>>24);
bytes[9] = (uint8_t)(m_stun_tansaction_id[0]>>16);
bytes[10] = (uint8_t)(m_stun_tansaction_id[0]>>8);
bytes[11] = (uint8_t)(m_stun_tansaction_id[0]);
bytes[12] = (uint8_t)(m_stun_tansaction_id[1]>>24);
bytes[13] = (uint8_t)(m_stun_tansaction_id[1]>>16);
bytes[14] = (uint8_t)(m_stun_tansaction_id[1]>>8);
bytes[15] = (uint8_t)(m_stun_tansaction_id[1]);
bytes[16] = (uint8_t)(m_stun_tansaction_id[2]>>24);
bytes[17] = (uint8_t)(m_stun_tansaction_id[2]>>16);
bytes[18] = (uint8_t)(m_stun_tansaction_id[2]>>8);
bytes[19] = (uint8_t)(m_stun_tansaction_id[2]);
bytes[20] = '\0';
printf("__GetPublicAddress> Querrying STUN server 132.177.123.6\n");
unsigned int dst = (132<<24)+(177<<16)+(123<<8)+6;
NetworkManager::getInstance()->setManualSocketsMode(true);
NetworkManager::getInstance()->getHost()->sendRawPacket(bytes, 20, TransportAddress(dst, 3478));
m_state = TEST_SENT;
}
if (m_state == TEST_SENT)
{
unsigned int dst = (132<<24)+(177<<16)+(123<<8)+6;
uint8_t* data = NetworkManager::getInstance()->getHost()->receiveRawPacket(TransportAddress(dst, 3478));
assert(data);
// check that the stun response is a response, contains the magic cookie and the transaction ID
if ( data[0] == 0b01 &&
data[1] == 0b01 &&
data[4] == (uint8_t)(m_stun_magic_cookie>>24) &&
data[5] == (uint8_t)(m_stun_magic_cookie>>16) &&
data[6] == (uint8_t)(m_stun_magic_cookie>>8) &&
data[7] == (uint8_t)(m_stun_magic_cookie))
{
if(
data[8] == (uint8_t)(m_stun_tansaction_id[0]>>24) &&
data[9] == (uint8_t)(m_stun_tansaction_id[0]>>16) &&
data[10] == (uint8_t)(m_stun_tansaction_id[0]>>8 ) &&
data[11] == (uint8_t)(m_stun_tansaction_id[0] ) &&
data[12] == (uint8_t)(m_stun_tansaction_id[1]>>24) &&
data[13] == (uint8_t)(m_stun_tansaction_id[1]>>16) &&
data[14] == (uint8_t)(m_stun_tansaction_id[1]>>8 ) &&
data[15] == (uint8_t)(m_stun_tansaction_id[1] ) &&
data[16] == (uint8_t)(m_stun_tansaction_id[2]>>24) &&
data[17] == (uint8_t)(m_stun_tansaction_id[2]>>16) &&
data[18] == (uint8_t)(m_stun_tansaction_id[2]>>8 ) &&
data[19] == (uint8_t)(m_stun_tansaction_id[2] ))
{
printf("__GetPublicAddress> The STUN server responded with a valid answer\n");
int message_size = data[2]*256+data[3];
// parse the stun message now:
bool finish = false;
uint8_t* attributes = data+20;
if (message_size == 0)
{
printf("__GetPublicAddress> STUN answer does not contain any information.\n");
finish = true;
}
if (message_size < 4) // cannot even read the size
{
printf("__GetPublicAddress> STUN message is not valid.\n");
finish = true;
}
uint16_t port;
uint32_t address;
bool valid = false;
while(!finish)
{
int type = attributes[0]*256+attributes[1];
int size = attributes[2]*256+attributes[3];
switch(type)
{
case 0:
case 1:
assert(size == 8);
assert(attributes[5] = 0x01); // IPv4 only
port = attributes[6]*256+attributes[7];
address = (attributes[8]<<24 & 0xFF000000)+(attributes[9]<<16 & 0x00FF0000)+(attributes[10]<<8 & 0x0000FF00)+(attributes[11] & 0x000000FF);
finish = true;
valid = true;
continue;
break;
default:
break;
}
attributes = attributes + 4 + size;
message_size -= 4 + size;
if (message_size == 0)
finish = true;
if (message_size < 4) // cannot even read the size
{
printf("__GetPublicAddress> STUN message is not valid.\n");
finish = true;
}
}
// finished parsing, we know our public transport address
if (valid)
{
printf("__The public address has been found : %i.%i.%i.%i:%i\n", address>>24&0xff, address>>16&0xff, address>>8&0xff, address&0xff, port);
m_state = ADDRESS_KNOWN;
NetworkManager::getInstance()->setManualSocketsMode(false);
TransportAddress* addr = static_cast<TransportAddress*>(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);
}
}

View File

@ -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

View File

@ -0,0 +1,74 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "network/protocols/hide_public_address.hpp"
#include "network/http_functions.hpp"
#include <stdio.h>
HidePublicAddress::HidePublicAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT)
{
}
HidePublicAddress::~HidePublicAddress()
{
}
void HidePublicAddress::notifyEvent(Event* event)
{
}
void HidePublicAddress::setup()
{
m_state = NONE;
}
void HidePublicAddress::update()
{
if (m_state == NONE)
{
char url[512];
sprintf(url, "http://stkconnect.freeserver.me/log.php?logout&nick=%s&pwd=%s", m_username.c_str(), m_password.c_str());
std::string result = HTTP::getPage(url);
if (result[0] == 's' && result[1] == 'u' && result[2] == 'c' && result[3] == 'c' && result[4] == 'e' && result[5] == 's' && result[6] == 's')
{
printf("__HidePublicAddress> Public address hidden successfully.\n");
m_state = DONE;
}
if (result[0] == 'f' && result[1] == 'a' && result[2] == 'i' && result[3] == 'l')
{
printf("__HidePublicAddress> Public address still visible. Re-set nick:password and retry.\n");
m_state = NONE;
pause();
}
}
else if (m_state == DONE)
{
m_listener->requestTerminate(this);
}
}
void HidePublicAddress::setUsername(std::string username)
{
m_username = username;
}
void HidePublicAddress::setPassword(std::string password)
{
m_password = password;
}

View File

@ -0,0 +1,49 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HIDE_PUBLIC_ADDRESS_HPP
#define HIDE_PUBLIC_ADDRESS_HPP
#include "network/protocol.hpp"
#include <string>
class HidePublicAddress : public Protocol
{
public:
HidePublicAddress(CallbackObject* callback_object);
virtual ~HidePublicAddress();
virtual void notifyEvent(Event* event);
virtual void setup();
virtual void update();
virtual void setUsername(std::string username);
virtual void setPassword(std::string password);
protected:
std::string m_username;
std::string m_password;
enum STATE
{
NONE,
DONE
};
STATE m_state;
};
#endif // HIDE_PUBLIC_ADDRESS_HPP

View File

@ -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.
#include "lobby_room_protocol.hpp"
#include <stdio.h>
LobbyRoomProtocol::LobbyRoomProtocol(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_LOBBY_ROOM)
{
}
LobbyRoomProtocol::~LobbyRoomProtocol()
{
}
void LobbyRoomProtocol::notifyEvent(Event* event)
{
if (event->type == EVENT_TYPE_MESSAGE)
{
printf("Message from %u : \"%s\"\n", event->peer->getAddress(), event->data.c_str());
}
}
void LobbyRoomProtocol::setup()
{
}
void LobbyRoomProtocol::update()
{
}
void LobbyRoomProtocol::sendMessage(std::string message)
{
}

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -16,30 +16,32 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_RACE_RESULT_MESSAGE_HPP
#define HEADER_RACE_RESULT_MESSAGE_HPP
#ifndef LOBBY_ROOM_PROTOCOL_HPP
#define LOBBY_ROOM_PROTOCOL_HPP
#include <vector>
#include "network/protocol.hpp"
#include "network/message.hpp"
/** This message is from the server to all clients to inform them about the
* result of a race. The clients wait for this message before they finish
* a race.
/*!
* \class LobbyRoomProtocol
* \brief Class used while the game is being prepared.
* This protocol starts when a server opens a game, or when a client joins a game.
* It is used to exchange data about the race settings, like kart selection.
*/
class RaceResultMessage : public Message
class LobbyRoomProtocol : public Protocol
{
struct RaceResult {
float m_time;
int m_score;
}; // RaceResult
private:
std::vector<RaceResult> m_all_results;
public:
RaceResultMessage();
RaceResultMessage(ENetPacket* pkt);
void addRaceResult(int kart_id, float time, int points);
void getRaceResult(int kart_id, float &time, int &points);
}; // RaceResultMessage
#endif
public:
LobbyRoomProtocol(CallbackObject* callback_object);
virtual ~LobbyRoomProtocol();
virtual void notifyEvent(Event* event);
virtual void setup();
virtual void update();
void sendMessage(std::string message);
protected:
};
#endif // LOBBY_ROOM_PROTOCOL_HPP

View File

@ -0,0 +1,84 @@
//
// 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 "show_public_address.hpp"
#include "../http_functions.hpp"
#include <stdio.h>
ShowPublicAddress::ShowPublicAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT)
{
}
ShowPublicAddress::~ShowPublicAddress()
{
}
void ShowPublicAddress::notifyEvent(Event* event)
{
}
void ShowPublicAddress::setup()
{
m_state = NONE;
if (m_public_ip == 0 || m_public_port == 0 || m_username == "" || m_password == "")
{
printf("__ShowPublicAddress> You have to set the public ip:port, username:password and the host nickname before starting this protocol.\n");
m_listener->requestTerminate(this);
}
}
void ShowPublicAddress::update()
{
if (m_state == NONE)
{
char url[512];
sprintf(url, "http://stkconnect.freeserver.me/log.php?set&nick=%s&ip=%u&port=%u&pwd=%s", m_username.c_str(), m_public_ip, m_public_port, m_password.c_str());
std::string result = HTTP::getPage(url);
if (result[0] == 's' && result[1] == 'u' && result[2] == 'c' && result[3] == 'c' && result[4] == 'e' && result[5] == 's' && result[6] == 's')
{
printf("__ShowPublicAddress> Address set.\n");
m_state = DONE;
}
if (result[0] == 'f' && result[1] == 'a' && result[2] == 'i' && result[3] == 'l')
{
printf("__ShowPublicAddress> Login fail. Please re-set username:password and unpause the protocol.\n");
m_state = NONE;
pause();
}
}
else if (m_state == DONE)
{
m_listener->requestTerminate(this);
}
}
void ShowPublicAddress::setUsername(std::string username)
{
m_username = username;
}
void ShowPublicAddress::setPassword(std::string password)
{
m_password = password;
}
void ShowPublicAddress::setPublicAddress(uint32_t ip, uint16_t port)
{
m_public_ip = ip;
m_public_port = port;
}

View File

@ -0,0 +1,53 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef SHOW_PUBLIC_ADDRESS_HPP
#define SHOW_PUBLIC_ADDRESS_HPP
#include "network/protocol.hpp"
#include <string>
class ShowPublicAddress : public Protocol
{
public:
ShowPublicAddress(CallbackObject* callback_object);
virtual ~ShowPublicAddress();
virtual void notifyEvent(Event* event);
virtual void setup();
virtual void update();
virtual void setUsername(std::string username);
virtual void setPassword(std::string password);
virtual void setPublicAddress(uint32_t ip, uint16_t port);
protected:
std::string m_username;
std::string m_password;
uint32_t m_public_ip;
uint16_t m_public_port;
enum STATE
{
NONE,
DONE
};
STATE m_state;
};
#endif // HIDE_PUBLIC_ADDRESS_HPP

View File

@ -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<RemoteKartInfo>& 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<kart_info.size(); i++)
{
len += getCharLength() // kart_info[i].getGlobalPlayerId())
+ getCharLength() // kart_info[i].getHostId())
+ getStringLength(kart_info[i].getKartName())
+ getCharLength() // kart_info[i].getLocalPlayerId())
+ kart_info[i].getPlayerName().size() + 1; // FIXME: encoding issues
}
const std::vector<std::string>& 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; i<kart_info.size(); i++)
{
addChar(kart_info[i].getGlobalPlayerId());
addChar(kart_info[i].getHostId());
addString(kart_info[i].getKartName());
addChar(kart_info[i].getLocalPlayerId());
addString( core::stringc(kart_info[i].getPlayerName().c_str()).c_str()); // FIXME: encoding issues
}
addStringVector(rkl);
} // RaceInfoMessage
// ----------------------------------------------------------------------------
RaceInfoMessage::RaceInfoMessage(ENetPacket* pkt):Message(pkt, MT_RACE_INFO)
{
race_manager->setMajorMode ( 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<RemoteKartInfo> kart_info;
kart_info.resize(getChar());
for(unsigned int i=0; i<kart_info.size(); i++)
{
kart_info[i].setGlobalPlayerId(getChar());
kart_info[i].setHostId(getChar());
kart_info[i].setKartName(getString());
kart_info[i].setLocalPlayerId(getChar());
kart_info[i].setPlayerName( core::stringw(getString().c_str()) );
}
// Set the player kart information
race_manager->setNumPlayers(kart_info.size());
for(unsigned int i=0; i<kart_info.size(); i++)
{
race_manager->setPlayerKart(i, kart_info[i]);
}
std::vector<std::string> rkl=getStringVector();
race_manager->setAIKartList(rkl);
} // RaceInfoMessage

View File

@ -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 <string>
#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

View File

@ -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; i<num_karts; i++)
{
const AbstractKart *kart = world->getKart(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; i<num_karts; i++)
{
AbstractKart *kart = world->getKart(i);
float time = getFloat();
char position = getChar();
kart->setPosition(position);
kart->finishedRace(time);
}
} // RaceResultMessage

View File

@ -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; i<num_karts; i++)
{
const AbstractKart* kart = world->getKart(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; i<m_item_info.size(); i++)
{
m_item_info[i].serialise(this);
}
// 3. Projectiles
// --------------
addShort(m_flyable_info.size());
for(unsigned int i=0; i<(unsigned int)m_flyable_info.size(); i++)
{
m_flyable_info[i].serialise(this);
}
// 4. Collisions
// -------------
addChar(m_collision_info.size());
for(unsigned int i=0; i<m_collision_info.size(); i++)
{
addChar(m_collision_info[i]);
}
m_collision_info.clear();
} // serialise
// ----------------------------------------------------------------------------
void RaceState::clear()
{
m_item_info.clear();
} // clear
// ----------------------------------------------------------------------------
/** Unserialises a race state message.
* This function unserialises the message, and updates the state of the race
* simulation appropriately.
*/
void RaceState::receive(ENetPacket *pkt)
{
Message::receive(pkt, MT_RACE_STATE);
// 1. Kart information
// -------------------
unsigned int num_karts = getChar();
World *world = World::getWorld();
for(unsigned int i=0; i<num_karts; i++)
{
KartControl kc(this);
// Currently not used!
Vec3 xyz = getVec3();
btQuaternion q = getQuaternion();
AbstractKart *kart = world->getKart(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; i<num_items; i++)
{
ItemInfo hi(this);
if(hi.m_item_id==-1) // Rescue triggered
new RescueAnimation(world->getKart(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; i<num_flyables; i++)
{
FlyableInfo f(this);
m_flyable_info[i] = f;
}
// 4. Collisions
// -------------
unsigned int num_collisions = getChar();
// Collisions are stored as pairs, so handle a pair at a time
for(unsigned int i=0; i<num_collisions; i+=2)
{
signed char kart_id1 = getChar();
signed char kart_id2 = getChar();
if(kart_id2==-1)
{ // kart - track collision
Vec3 normal(0, 1, 0); // need to be fixed for online
world->getKart(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<num_collisions; i+=2)
clear(); // free message buffer
} // receive
// ----------------------------------------------------------------------------

View File

@ -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 <vector>
#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<ItemInfo> m_item_info;
/** Updates about existing flyables. */
AlignedArray<FlyableInfo> m_flyable_info;
/** Stores the controls of each kart at the beginning of its update(). */
std::vector<KartControl> m_kart_controls;
/** Collision information. This vector stores information about which
* kart collided with which kart or track (kartid=-1) */
std::vector<signed char> 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

View File

@ -0,0 +1,123 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "server_network_manager.hpp"
#include "protocols/get_public_address.hpp"
#include "protocols/hide_public_address.hpp"
#include "protocols/show_public_address.hpp"
#include "protocols/get_peer_address.hpp"
#include "protocols/connect_to_server.hpp"
#include <enet/enet.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
ServerNetworkManager::ServerNetworkManager()
{
m_localhost = NULL;
}
ServerNetworkManager::~ServerNetworkManager()
{
}
void ServerNetworkManager::run()
{
if (enet_initialize() != 0)
{
printf("Could not initialize enet.\n");
return;
}
NetworkManager::run();
}
void ServerNetworkManager::start()
{
m_localhost = new STKHost();
m_localhost->setupServer(STKHost::HOST_ANY, 7321, 32, 2, 0, 0);
m_localhost->startListening();
printf("Server now setup, listening on port 7321.\n");
printf("_NetworkInterface>Starting the global protocol\n");
// step 1 : retreive public address
Protocol* protocol = new GetPublicAddress(&m_public_address);
ProtocolManager::getInstance()->requestStart(protocol);
while (ProtocolManager::getInstance()->getProtocolState(protocol) != PROTOCOL_STATE_TERMINATED )
{
}
printf("_NetworkInterface> The public address is known.\n");
// step 2 : show the public address for others (here, the server)
ShowPublicAddress* spa = new ShowPublicAddress(NULL);
spa->setPassword(m_player_login.password);
spa->setUsername(m_player_login.username);
spa->setPublicAddress(m_public_address.ip, m_public_address.port);
ProtocolManager::getInstance()->requestStart(spa);
while (ProtocolManager::getInstance()->getProtocolState(spa) != PROTOCOL_STATE_TERMINATED )
{
}
printf("_NetworkInterface> The public address is being shown online.\n");
}
bool ServerNetworkManager::connectToPeer(std::string peer_username)
{
printf("_NetworkInterface>Starting the connection to host protocol\n");
// step 3 : get the peer's addres.
TransportAddress addr;
GetPeerAddress* gpa = new GetPeerAddress(&addr);
gpa->setPeerName(peer_username);
ProtocolManager::getInstance()->requestStart(gpa);
while (ProtocolManager::getInstance()->getProtocolState(gpa) != PROTOCOL_STATE_TERMINATED )
{
}
printf("_NetworkInterface> The public address of the peer is known.\n");
// step 2 : connect to the peer
ConnectToServer* cts = new ConnectToServer(NULL);
cts->setServerAddress(addr.ip, addr.port);
ProtocolManager::getInstance()->requestStart(cts);
while (ProtocolManager::getInstance()->getProtocolState(cts) != PROTOCOL_STATE_TERMINATED )
{
}
bool success = false;
if (isConnectedTo(addr))
{
success = true;
printf("_NetworkInterface> CONNECTION SUCCES : YOU ARE NOW CONNECTED TO A PEER.\n");
}
else
{
printf("_NetworkInterface> We are NOT connected to the server.\n");
}
return success;
}
void ServerNetworkManager::packetReceived(char* data)
{
printf("ServerNetworkManager::packetReceived()\n");
puts(data);
sendPacket(data);
}
void ServerNetworkManager::sendPacket(char* data)
{
m_localhost->broadcastPacket(data);
}

View File

@ -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_manager.hpp"
class ServerNetworkManager : public NetworkManager
{
friend class Singleton<NetworkManager>;
public:
static ServerNetworkManager* getInstance()
{
return Singleton<NetworkManager>::getInstance<ServerNetworkManager>();
}
virtual void run();
void start();
bool connectToPeer(std::string peer_username);
virtual void packetReceived(char* data);
virtual void sendPacket(char* data);
virtual bool isServer() { return false; }
protected:
ServerNetworkManager();
virtual ~ServerNetworkManager();
};
#endif // SERVER_NETWORK_MANAGER_HPP

63
src/network/singleton.hpp Normal file
View File

@ -0,0 +1,63 @@
//
// 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 <iostream>
template <typename T>
class Singleton
{
protected:
Singleton () { }
virtual ~Singleton () { std::cout << "destroying singleton." << std::endl; delete m_singleton; }
public:
template<typename S>
static S *getInstance ()
{
if (m_singleton == NULL)
m_singleton = new S;
S* result = (dynamic_cast<S*> (m_singleton));
if (result == NULL)
std::cout << "THE SINGLETON HAS NOT BEEN REALOCATED, BUT IS NOT OF THE REQUESTED TYPE." << std::endl;
return result;
}
static T *getInstance()
{
return (dynamic_cast<T*> (m_singleton));
}
static void kill ()
{
if (NULL != m_singleton)
{
delete m_singleton;
m_singleton = NULL;
}
}
private:
static T *m_singleton;
};
template <typename T> T *Singleton<T>::m_singleton = NULL;
#endif // SINGLETON_HPP

218
src/network/stk_host.cpp Normal file
View File

@ -0,0 +1,218 @@
//
// 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 "stk_host.hpp"
#include "network_manager.hpp"
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <arpa/inet.h>
// ----------------------------------------------------------------------------
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 = (pthread_t*)(malloc(sizeof(pthread_t)));
}
// ----------------------------------------------------------------------------
STKHost::~STKHost()
{
}
// ----------------------------------------------------------------------------
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)
{
fprintf (stderr, "An error occurred while trying to create an ENet \
server host.\n");
exit (EXIT_FAILURE);
}
}
// ----------------------------------------------------------------------------
void STKHost::setupClient(int peer_count, int channel_limit,
uint32_t max_incoming_bandwidth,
uint32_t max_outgoing_bandwidth)
{
m_host = enet_host_create(NULL, peer_count, channel_limit,
max_incoming_bandwidth, max_outgoing_bandwidth);
if (m_host == NULL)
{
fprintf (stderr, "An error occurred while trying to create an ENet \
client host.\n");
exit (EXIT_FAILURE);
}
}
// ----------------------------------------------------------------------------
void STKHost::startListening()
{
pthread_create(m_listening_thread, NULL, &STKHost::receive_data, this);
}
// ----------------------------------------------------------------------------
void STKHost::stopListening()
{
pthread_cancel(*m_listening_thread);
}
// ----------------------------------------------------------------------------
void STKHost::sendRawPacket(uint8_t* data, int length, TransportAddress dst)
{
struct sockaddr_in to;
int to_len = sizeof(to);
memset(&to,0,to_len);
to.sin_family = AF_INET;
to.sin_port = htons(dst.port);
to.sin_addr.s_addr = htonl(dst.ip);
sendto(m_host->socket, data, length, 0,(sockaddr*)&to, to_len);
}
// ----------------------------------------------------------------------------
uint8_t* STKHost::receiveRawPacket()
{
uint8_t* buffer; // max size needed normally (only used for stun)
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048));
memset(buffer, 0, 2048);
int len = recv(m_host->socket,buffer,2048, 0);
int i = 0;
// wait to receive the message because enet sockets are non-blocking
while(len < 0)
{
i++;
len = recv(m_host->socket,buffer,2048, 0);
usleep(1000); // wait 1 millisecond between two checks
}
printf("Packet received after %i milliseconds\n", i);
return buffer;
}
// ----------------------------------------------------------------------------
uint8_t* STKHost::receiveRawPacket(TransportAddress sender)
{
uint8_t* buffer; // max size needed normally (only used for stun)
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048));
memset(buffer, 0, 2048);
socklen_t from_len;
struct sockaddr addr;
from_len = sizeof(addr);
int len = recvfrom(m_host->socket, buffer, 2048, 0, &addr, &from_len);
int i = 0;
// wait to receive the message because enet sockets are non-blocking
while(len < 0 || (
(uint8_t)(addr.sa_data[2]) != (sender.ip>>24&0xff)
&& (uint8_t)(addr.sa_data[3]) != (sender.ip>>16&0xff)
&& (uint8_t)(addr.sa_data[4]) != (sender.ip>>8&0xff)
&& (uint8_t)(addr.sa_data[5]) != (sender.ip&0xff)))
{
i++;
len = recvfrom(m_host->socket, buffer, 2048, 0, &addr, &from_len);
usleep(1000); // wait 1 millisecond between two checks
}
if (addr.sa_family == AF_INET)
{
char s[20];
inet_ntop(AF_INET, &(((struct sockaddr_in *)&addr)->sin_addr), s, 20);
printf("IPv4 Address %s\n", s);
}
printf("Packet received after %i milliseconds\n", i);
return buffer;
}
// ----------------------------------------------------------------------------
void STKHost::broadcastPacket(char* data)
{
ENetPacket* packet = enet_packet_create(data, strlen(data)+1,
ENET_PACKET_FLAG_RELIABLE);
enet_host_broadcast(m_host, 0, packet);
}
// ----------------------------------------------------------------------------
bool STKHost::peerExists(TransportAddress peer)
{
for (unsigned int i = 0; i < m_host->peerCount; i++)
{
if (m_host->peers[i].address.host == peer.ip &&
m_host->peers[i].address.port == peer.port)
{
return true;
}
}
return false;
}
// ----------------------------------------------------------------------------
bool STKHost::isConnectedTo(TransportAddress peer)
{
for (unsigned int i = 0; i < m_host->peerCount; i++)
{
if (m_host->peers[i].address.host == peer.ip &&
m_host->peers[i].address.port == peer.port &&
m_host->peers[i].state == ENET_PEER_STATE_CONNECTED)
{
return true;
}
}
return false;
}

141
src/network/stk_host.hpp Normal file
View File

@ -0,0 +1,141 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/*! \file stk_host.hpp
* \brief Defines an interface to use network low-level functions easily.
*/
#ifndef STK_HOST_HPP
#define STK_HOST_HPP
#include <enet/enet.h>
#include "types.hpp"
/*! \class STKHost
* \brief Represents the local host.
* This host is either a server host or a client host. A client host is in
* charge of connecting to a server. A server opens a socket for incoming
* connections.
* By default, this host will use ENet to exchange packets. It also defines an
* interface for ENet use. Nevertheless, this class can be used to send and/or
* receive packets whithout ENet adding its headers.
* This class is used by the Network Manager to send packets.
*/
class STKHost
{
friend class STKPeer; // allow direct enet modifications in implementations
public:
/*! \enum HOST_TYPE
* \brief Defines three host types for the server.
* These values tells the host where he will accept connections from.
*/
enum HOST_TYPE
{
HOST_ANY = 0, //!< Any host.
HOST_BROADCAST = 0xFFFFFFFF, //!< Defines the broadcast address.
PORT_ANY = 0 //!< Any port.
};
/*! \brief Constructor */
STKHost();
/*! \brief Destructor */
virtual ~STKHost();
/*! \brief Thread function checking if data is received.
* This function tries to get data from network low-level functions as
* often as possible. When something is received, it generates an
* event and passes it to the Network Manager.
* \param self : used to pass the ENet host to the function.
*/
static void* receive_data(void* self);
/*! \brief Setups the host as a server.
* \param address : The IPv4 address of incoming connections.
* \param port : The port on which the server listens.
* \param peer_count : The maximum number of peers.
* \param channel_limit : The maximum number of channels per peer.
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
*/
void setupServer(uint32_t address, uint16_t port,
int peer_count, int channel_limit,
uint32_t max_incoming_bandwidth,
uint32_t max_outgoing_bandwidth);
/*! \brief Setups the host as a client.
* In fact there is only one peer connected to this host.
* \param peer_count : The maximum number of peers.
* \param channel_limit : The maximum number of channels per peer.
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
*/
void setupClient(int peer_count, int channel_limit,
uint32_t max_incoming_bandwidth,
uint32_t max_outgoing_bandwidth);
/*! \brief Starts the listening of events from ENet.
* Starts a thread that updates it as often as possible.
*/
void startListening();
/*! \brief Stops the listening of events from ENet.
* Stops the thread that was receiving events.
*/
void stopListening();
/*! \brief Sends a packet whithout ENet adding its headers.
* This function is used in particular to achieve the STUN protocol.
* \param data : Data to send.
* \param length : Length of the sent data.
* \param dst : Destination of the packet.
*/
void sendRawPacket(uint8_t* data, int length,
TransportAddress dst);
/*! \brief Receives a packet directly from the network interface.
* Receive a packet whithout ENet processing it.
* \return A string containing the data of the received packet.
*/
uint8_t* receiveRawPacket();
/*! \brief Receives a packet directly from the network interface and
* filter its address.
* Receive a packet whithout ENet processing it. Checks that the
* sender of the packet is the one that corresponds to the sender
* parameter. Does not check the port right now.
* \param sender : Transport address of the original sender of the
* wanted packet.
* \return A string containing the data of the received packet
* matching the sender's ip address.
*/
uint8_t* receiveRawPacket(TransportAddress sender);
/*! \brief Broadcasts a packet to all peers.
* \param data : Data to send.
*/
void broadcastPacket(char* data);
/*! \brief Tells if a peer is known.
* \return True if the peer is known, false elseway.
*/
bool peerExists(TransportAddress peer_address);
/*! \brief Tells if a peer is known and connected.
* \return True if the peer is known and connected, false elseway.
*/
bool isConnectedTo(TransportAddress peer_address);
protected:
ENetHost* m_host; //!< ENet host interfacing sockets.
pthread_t* m_listening_thread; //!< Thread listening network events.
};
#endif // STK_HOST_HPP

77
src/network/stk_peer.cpp Normal file
View File

@ -0,0 +1,77 @@
//
// 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 "stk_peer.hpp"
#include <stdio.h>
#include <string.h>
STKPeer::STKPeer()
{
m_peer = NULL;
}
STKPeer::~STKPeer()
{
if (m_peer)
delete m_peer;
}
bool STKPeer::connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data)
{
ENetAddress address;
address.host = host.ip;
address.port = host.port;
ENetPeer* peer = enet_host_connect(localhost->m_host, &address, 2, 0);
if (peer == NULL)
{
printf("Could not try to connect to server.\n");
return false;
}
printf("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(char* data)
{
//printf("sending packet to %i.%i.%i.%i:%i", (m_peer->address.host>>24)&0xff,(m_peer->address.host>>16)&0xff,(m_peer->address.host>>8)&0xff,(m_peer->address.host>>0)&0xff,m_peer->address.port);
ENetPacket* packet = enet_packet_create(data, strlen(data)+1,ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(m_peer, 0, packet);
}
uint32_t STKPeer::getAddress()
{
return m_peer->address.host;
}
uint16_t STKPeer::getPort()
{
return m_peer->address.port;
}
bool STKPeer::isConnected()
{
printf("PEER STATE %i\n", m_peer->state);
return (m_peer->state == ENET_PEER_STATE_CONNECTED);
}
bool STKPeer::operator==(ENetPeer* peer)
{
return peer==m_peer;
}

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -16,22 +16,30 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_NETWORK_KART_HPP
#define HEADER_NETWORK_KART_HPP
#ifndef STK_PEER_HPP
#define STK_PEER_HPP
#include "karts/kart.hpp"
#include "stk_host.hpp"
#include <enet/enet.h>
class Track;
class NetworkKart : public Kart
class STKPeer
{
private:
int m_global_player_id; // to identify this kart to the network manager
public:
NetworkKart(const std::string& kart_name, unsigned int world_kart_id,
int position, const btTransform& init_transform,
int global_player_id, RaceManager::KartType type);
void setControl(const KartControl& kc);
virtual bool isNetworkKart() const { return true; }
}; // NetworkKart
#endif
friend class Event;
public:
STKPeer();
virtual ~STKPeer();
virtual void sendPacket(char* data);
static bool connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data);
bool isConnected();
uint32_t getAddress();
uint16_t getPort();
bool operator==(ENetPeer* peer);
protected:
ENetPeer* m_peer;
};
#endif // STK_PEER_HPP

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -16,16 +16,17 @@
// 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 "time.hpp"
#include "network/message.hpp"
class WorldLoadedMessage : public Message
namespace Time
{
// 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
double getSeconds()
{
time_t timer;
time(&timer);
struct tm y2k;
y2k.tm_hour = 0; y2k.tm_min = 0; y2k.tm_sec = 0;
y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;
return difftime(timer,mktime(&y2k)); // get the seconds elapsed since january 2000
}
}

View File

@ -1,6 +1,6 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
// Copyright (C) 2013 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -16,18 +16,14 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_RACE_INFO_MESSAGE_HPP
#define HEADER_RACE_INFO_MESSAGE_HPP
#ifndef TIME_HPP
#define TIME_HPP
#include <vector>
#include <time.h>
#include "network/message.hpp"
#include "network/remote_kart_info.hpp"
class RaceInfoMessage : public Message
namespace Time
{
public:
RaceInfoMessage(const std::vector<RemoteKartInfo>& kart_info);
RaceInfoMessage(ENetPacket* pkt);
}; // RaceInfoMessage
#endif
double getSeconds();
}
#endif // TIME_HPP_INCLUDED

65
src/network/types.hpp Normal file
View File

@ -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.
/*! \file types.hpp
* \brief Declares the general types that are used by the network.
*/
#ifndef TYPES_HPP
#define TYPES_HPP
#include <string>
#include <stdint.h>
/*! \class CallbackObject
* \brief Class that must be inherited to pass objects to protocols.
*/
class CallbackObject
{
public:
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; }
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() {}
std::string username; //!< Username of the player
std::string password; //!< Password of the player
};
#endif // TYPES_HPP

View File

@ -20,9 +20,12 @@
#include "animations/three_d_animation.hpp"
#include "config/user_config.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "karts/rescue_animation.hpp"
#include "network/race_state.hpp"
#include "items/flyable.hpp"
#include "items/item.hpp"
#include "modes/world.hpp"
#include "graphics/stars.hpp"
#include "karts/explosion_animation.hpp"
#include "physics/btKart.hpp"
@ -157,8 +160,8 @@ void Physics::update(float dt)
{
AbstractKart *a=p->getUserPointer(0)->getPointerKart();
AbstractKart *b=p->getUserPointer(1)->getPointerKart();
race_state->addCollision(a->getWorldKartId(),
b->getWorldKartId());
// race_state->addCollision(a->getWorldKartId(),
// b->getWorldKartId());
KartKartCollision(p->getUserPointer(0)->getPointerKart(),
p->getContactPointCS(0),
p->getUserPointer(1)->getPointerKart(),
@ -457,7 +460,7 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
else if(upB->is(UserPointer::UP_KART))
{
AbstractKart *kart=upB->getPointerKart();
race_state->addCollision(kart->getWorldKartId());
// race_state->addCollision(kart->getWorldKartId());
int n = contact_manifold->getContactPoint(0).m_index0;
const Material *m
= n>=0 ? upA->getPointerTriangleMesh()->getMaterial(n)
@ -477,7 +480,7 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
if(upB->is(UserPointer::UP_TRACK))
{
AbstractKart *kart = upA->getPointerKart();
race_state->addCollision(kart->getWorldKartId());
// race_state->addCollision(kart->getWorldKartId());
int n = contact_manifold->getContactPoint(0).m_index1;
const Material *m
= n>=0 ? upB->getPointerTriangleMesh()->getMaterial(n)

View File

@ -20,6 +20,7 @@
#define HEADER_HISTORY_HPP
#include <vector>
#include <string>
#include "LinearMath/btQuaternion.h"

View File

@ -143,9 +143,9 @@ void RaceManager::setLocalKartInfo(unsigned int player_id,
assert(0<=player_id && player_id <m_local_player_karts.size());
assert(kart_properties_manager->getKart(kart) != NULL);
m_local_player_karts[player_id] = RemoteKartInfo(player_id, kart,
/* m_local_player_karts[player_id] = RemoteKartInfo(player_id, kart,
StateManager::get()->getActivePlayerProfile(player_id)->getName(),
network_manager->getMyHostId());
network_manager->getMyHostId());*/
} // setLocalKartInfo
//-----------------------------------------------------------------------------
@ -293,7 +293,7 @@ void RaceManager::startNew(bool from_overworld)
// Create the kart status data structure to keep track of scores, times, ...
// ==========================================================================
m_kart_status.clear();
printf("%d %d %d\n", (unsigned int)m_num_karts, m_ai_kart_list.size(), m_player_karts.size());
assert((unsigned int)m_num_karts == m_ai_kart_list.size()+m_player_karts.size());
// First add the AI karts (randomly chosen)
@ -321,8 +321,8 @@ void RaceManager::startNew(bool from_overworld)
// -------------------------------------------------
for(int i=m_player_karts.size()-1; i>=0; i--)
{
KartType kt=(m_player_karts[i].getHostId()==network_manager->getMyHostId())
? KT_PLAYER : KT_NETWORK_PLAYER;
KartType kt= KT_PLAYER; //(m_player_karts[i].getHostId()==network_manager->getMyHostId())
//? KT_PLAYER : KT_NETWORK_PLAYER;
m_kart_status.push_back(KartStatus(m_player_karts[i].getKartName(), i,
m_player_karts[i].getLocalPlayerId(),
m_player_karts[i].getGlobalPlayerId(),
@ -510,20 +510,20 @@ void RaceManager::next()
user_config->saveConfig();
}
if(network_manager->getMode()==NetworkManager::NW_SERVER)
network_manager->beginReadySetGoBarrier();
else
network_manager->setState(NetworkManager::NS_WAIT_FOR_RACE_DATA);
// if(network_manager->getMode()==NetworkManager::NW_SERVER)
// network_manager->beginReadySetGoBarrier();
// else
// network_manager->setState(NetworkManager::NS_WAIT_FOR_RACE_DATA);
startNextRace();
}
else
{
// Back to main menu. Change the state of the state of the
// network manager.
if(network_manager->getMode()==NetworkManager::NW_SERVER)
network_manager->setState(NetworkManager::NS_MAIN_MENU);
else
network_manager->setState(NetworkManager::NS_WAIT_FOR_AVAILABLE_CHARACTERS);
// if(network_manager->getMode()==NetworkManager::NW_SERVER)
// network_manager->setState(NetworkManager::NS_MAIN_MENU);
// else
// network_manager->setState(NetworkManager::NS_WAIT_FOR_AVAILABLE_CHARACTERS);
exitRace();
}
} // next
@ -753,7 +753,7 @@ void RaceManager::startGP(const GrandPrixData* gp, bool from_overworld)
StateManager::get()->enterGameState();
setGrandPrix(*gp);
setCoinTarget( 0 ); // Might still be set from a previous challenge
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX);
startNew(from_overworld);
@ -778,7 +778,7 @@ void RaceManager::startSingleRace(const std::string &track_ident,
setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
setCoinTarget( 0 ); // Might still be set from a previous challenge
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
startNew(from_overworld);
}

View File

@ -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;

View File

@ -199,7 +199,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")
@ -226,7 +226,7 @@ GUIEngine::EventPropagation SelectChallengeDialog::processEvent(const std::strin
}
// Sets up kart info, including random list of kart for AI
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
race_manager->startNew(true);
irr_driver->hidePointer();

View File

@ -82,7 +82,7 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i
->setSinglePlayer( StateManager::get()->getActivePlayer(0) );
StateManager::get()->enterGameState();
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
race_manager->startNew(false);
}
else if (name == "category")

View File

@ -331,7 +331,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
->setSinglePlayer( StateManager::get()->getActivePlayer(0) );
StateManager::get()->enterGameState();
network_manager->setupPlayerKartInfo();
// network_manager->setupPlayerKartInfo();
race_manager->startNew(false);
}
else if (selection == "story")
@ -402,4 +402,4 @@ void MainMenuScreen::onDisabledItemClicked(const std::string& item)
new MessageDialog( _("Please wait while the add-ons are loading"));
}
}
} // onDisabledItemClicked
} // onDisabledItemClicked