Merge branch 'master' of github.com:supertuxkart/stk-code
This commit is contained in:
commit
d2e6a10026
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
|
||||
<div x="5%" y="2%" width="90%" height="96%" layout="vertical-row" >
|
||||
|
||||
<header I18N="Title for challenges screen" text="Challenges - Trophy Room" text_align="center" align="center" width="80%" />
|
||||
|
||||
<spacer height="5" width="100%"/>
|
||||
|
||||
<box width="100%" proportion="5" layout="vertical-row">
|
||||
|
||||
<ribbon_grid id="challenges" proportion="8" width="100%"
|
||||
label_location="bottom" align="center" child_width="128" child_height="128" />
|
||||
|
||||
|
||||
<spacer proportion="1" width="100%"/>
|
||||
</box>
|
||||
</div>
|
||||
</stkgui>
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="10%" width="96%" height="80%" layout="vertical-row" >
|
||||
|
||||
<label id="title" width="100%" text_align="center" word_wrap="true"
|
||||
I18N="In the 'add new player' dialog" text="Enter the new player's name" proportion="1" />
|
||||
|
||||
<spacer height="25" width="10" />
|
||||
|
||||
<textbox id="textfield" width="75%" I18N="In the 'add new player' dialog" align="center"/>
|
||||
|
||||
<spacer height="20" width="20" />
|
||||
|
||||
<buttonbar proportion="1" id="options" width="100%" height="100%">
|
||||
<button id="ok" I18N="In the 'add new player' dialog" text="OK" align="center"/>
|
||||
<button id="cancel" I18N="In the 'add new player' dialog" text="Cancel" align="center"/>
|
||||
</buttonbar>
|
||||
<spacer height="15" width="20" />
|
||||
|
||||
</div>
|
||||
</stkgui>
|
@ -65,6 +65,7 @@ SavedGrandPrix::SavedGPKart::SavedGPKart(GroupUserConfigParam * group,
|
||||
// ============================================================================
|
||||
SavedGrandPrix::SavedGrandPrix(unsigned int player_id,
|
||||
const std::string &gp_id,
|
||||
RaceManager::MinorRaceModeType race_type,
|
||||
RaceManager::Difficulty difficulty,
|
||||
int player_karts,
|
||||
int last_track,
|
||||
@ -74,6 +75,7 @@ SavedGrandPrix::SavedGrandPrix(unsigned int player_id,
|
||||
"Represents the saved state of a GP"),
|
||||
m_player_id(player_id, "player_id", &m_savedgp_group),
|
||||
m_gp_id(gp_id.c_str(), "gp_id", &m_savedgp_group),
|
||||
m_race_type((int)race_type,"race_type", &m_savedgp_group),
|
||||
m_difficulty((int)difficulty,"difficulty", &m_savedgp_group),
|
||||
m_player_karts(player_karts,"player_karts", &m_savedgp_group),
|
||||
m_next_track(last_track,"last_track", &m_savedgp_group),
|
||||
@ -98,6 +100,7 @@ SavedGrandPrix::SavedGrandPrix(const XMLNode* node)
|
||||
"Represents the saved state of a GP"),
|
||||
m_player_id (0, "player_id", &m_savedgp_group),
|
||||
m_gp_id ("-", "gp_id", &m_savedgp_group),
|
||||
m_race_type (0,"race_type", &m_savedgp_group),
|
||||
m_difficulty (0,"difficulty", &m_savedgp_group),
|
||||
m_player_karts(0,"player_karts", &m_savedgp_group),
|
||||
m_next_track (0,"last_track", &m_savedgp_group),
|
||||
@ -106,6 +109,7 @@ SavedGrandPrix::SavedGrandPrix(const XMLNode* node)
|
||||
//m_player_group.findYourDataInAChildOf(node);
|
||||
m_player_id. findYourDataInAnAttributeOf(node);
|
||||
m_gp_id. findYourDataInAnAttributeOf(node);
|
||||
m_race_type. findYourDataInAnAttributeOf(node);
|
||||
m_difficulty. findYourDataInAnAttributeOf(node);
|
||||
m_player_karts.findYourDataInAnAttributeOf(node);
|
||||
m_next_track. findYourDataInAnAttributeOf(node);
|
||||
|
@ -66,6 +66,9 @@ protected:
|
||||
|
||||
/** Identifier of this GP. */
|
||||
StringUserConfigParam m_gp_id;
|
||||
|
||||
/** Race type at which this GP was run. */
|
||||
IntUserConfigParam m_race_type;
|
||||
|
||||
/** Difficulty at which this GP was run. */
|
||||
IntUserConfigParam m_difficulty;
|
||||
@ -88,6 +91,7 @@ public:
|
||||
*/
|
||||
SavedGrandPrix(unsigned int player_id,
|
||||
const std::string &gp_id,
|
||||
RaceManager::MinorRaceModeType race_type,
|
||||
RaceManager::Difficulty difficulty,
|
||||
int player_karts,
|
||||
int last_track,
|
||||
@ -110,6 +114,10 @@ public:
|
||||
/** Returns the grand prix id. */
|
||||
std::string getGPID() const { return m_gp_id; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the race type of this GP. */
|
||||
int getRaceType() const { return m_race_type; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the difficulty of this GP. */
|
||||
int getDifficulty() const { return m_difficulty; }
|
||||
@ -148,12 +156,14 @@ public:
|
||||
* NULL if no matching GP was found. */
|
||||
static SavedGrandPrix* getSavedGP(unsigned int player,
|
||||
const std::string &gpid,
|
||||
RaceManager::MinorRaceModeType race_type,
|
||||
const unsigned int number_of_players)
|
||||
{
|
||||
for (unsigned int n=0; n<UserConfigParams::m_saved_grand_prix_list.size(); n++)
|
||||
{
|
||||
SavedGrandPrix* gp = &UserConfigParams::m_saved_grand_prix_list[n];
|
||||
if (gp->getGPID() == gpid &&
|
||||
gp->getRaceType() == race_type &&
|
||||
gp->getPlayerID() == player &&
|
||||
gp->getPlayerKarts() == (int)number_of_players)
|
||||
return gp;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
@ -127,11 +128,16 @@ Material* MaterialManager::getDefaultMaterial(video::E_MATERIAL_TYPE shader_type
|
||||
|
||||
// TODO: workaround, should not hardcode these material types here?
|
||||
// Try to find a cleaner way
|
||||
if (shader_type == Shaders::getShader(ShaderType::ES_OBJECT_UNLIT))
|
||||
// If graphics are disabled, shaders should not be accessed (getShader
|
||||
// asserts that shaders are initialised).
|
||||
if(!ProfileWorld::isNoGraphics() &&
|
||||
shader_type == Shaders::getShader(ShaderType::ES_OBJECT_UNLIT))
|
||||
default_material->setShaderType(Material::SHADERTYPE_SOLID_UNLIT);
|
||||
else if (shader_type == Shaders::getShader(ShaderType::ES_OBJECTPASS_REF))
|
||||
else if (!ProfileWorld::isNoGraphics() &&
|
||||
shader_type == Shaders::getShader(ShaderType::ES_OBJECTPASS_REF))
|
||||
default_material->setShaderType(Material::SHADERTYPE_ALPHA_TEST);
|
||||
//else if (shader_type == Shaders::getShader(ShaderType::ES_OBJECTPASS))
|
||||
//else if (!ProfileWorld::isNoGraphics() &&
|
||||
// shader_type == Shaders::getShader(ShaderType::ES_OBJECTPASS))
|
||||
// default_material->setShaderType(Material::SHADERTYPE_ALPHA_BLEND);
|
||||
else
|
||||
default_material->setShaderType(Material::SHADERTYPE_SOLID);
|
||||
|
@ -690,7 +690,8 @@ EventPropagation RibbonWidget::transmitEvent(Widget* w,
|
||||
// bring focus back to enclosing ribbon widget
|
||||
this->setFocusForPlayer( playerID );
|
||||
|
||||
if (m_selection[playerID] != -1)
|
||||
if (m_selection[playerID] > -1 &&
|
||||
m_selection[playerID] < (int)(m_active_children.size()))
|
||||
{
|
||||
if (m_active_children[m_selection[playerID]].m_deactivated)
|
||||
{
|
||||
|
@ -64,6 +64,7 @@ namespace irr {
|
||||
|
||||
|
||||
std::vector<std::string> FileManager::m_root_dirs;
|
||||
std::string FileManager::m_stdout_filename = "stdout.log";
|
||||
|
||||
#ifdef __APPLE__
|
||||
// dynamic data path detection onmac
|
||||
@ -1044,6 +1045,15 @@ std::string FileManager::checkAndCreateLinuxDir(const char *env_name,
|
||||
} // checkAndCreateLinuxDir
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the name for the stdout log file.
|
||||
* \param filename Filename to use (relative to the user config dir).
|
||||
*/
|
||||
void FileManager::setStdoutName(const std::string& filename)
|
||||
{
|
||||
m_stdout_filename = filename;
|
||||
} // setStdoutName
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Redirects output to go into files in the user's config directory
|
||||
* instead of to the console. It keeps backup copies of previous stdout files
|
||||
@ -1053,7 +1063,7 @@ void FileManager::redirectOutput()
|
||||
{
|
||||
// Do a simple log rotate: stdout.log.2 becomes stdout.log.3 etc
|
||||
const int NUM_BACKUPS=3;
|
||||
std::string logoutfile = getUserConfigFile("stdout.log");
|
||||
std::string logoutfile = getUserConfigFile(m_stdout_filename);
|
||||
for(int i=NUM_BACKUPS; i>1; i--)
|
||||
{
|
||||
std::ostringstream out_old;
|
||||
|
@ -69,6 +69,9 @@ private:
|
||||
/** The list of all root directories. */
|
||||
static std::vector<std::string> m_root_dirs;
|
||||
|
||||
/** Name of stdout file. */
|
||||
static std::string m_stdout_filename;
|
||||
|
||||
/** Directory to store screenshots in. */
|
||||
std::string m_screenshot_dir;
|
||||
|
||||
@ -109,6 +112,7 @@ public:
|
||||
~FileManager();
|
||||
void init();
|
||||
static void addRootDirs(const std::string &roots);
|
||||
static void setStdoutName(const std::string &name);
|
||||
io::IXMLReader *createXMLReader(const std::string &filename);
|
||||
XMLNode *createXMLTree(const std::string &filename);
|
||||
XMLNode *createXMLTreeFromString(const std::string & content);
|
||||
|
@ -1252,6 +1252,8 @@ void Kart::update(float dt)
|
||||
{
|
||||
m_body->getBroadphaseHandle()->m_collisionFilterGroup = old_group;
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Kart::Update (material)", 0x60, 0x34, 0x7F);
|
||||
handleMaterialGFX();
|
||||
const Material* material=m_terrain_info->getMaterial();
|
||||
if (!material) // kart falling off the track
|
||||
@ -1309,6 +1311,7 @@ void Kart::update(float dt)
|
||||
#endif
|
||||
}
|
||||
} // if there is material
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
// Check if any item was hit.
|
||||
// check it if we're not in a network world, or if we're on the server (when network mode is on)
|
||||
|
@ -1265,9 +1265,9 @@ int main(int argc, char *argv[] )
|
||||
handleCmdLineOutputModifier();
|
||||
|
||||
if(CommandLine::has("--root", &s))
|
||||
{
|
||||
FileManager::addRootDirs(s);
|
||||
}
|
||||
if (CommandLine::has("--stdout", &s))
|
||||
FileManager::setStdoutName(s);
|
||||
|
||||
// Init the minimum managers so that user config exists, then
|
||||
// handle all command line options that do not need (or must
|
||||
|
@ -954,7 +954,7 @@ void World::update(float dt)
|
||||
m_physics->update(dt);
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("World::update (AI)", 0x40, 0x7F, 0x00);
|
||||
PROFILER_PUSH_CPU_MARKER("World::update (Kart::upate)", 0x40, 0x7F, 0x00);
|
||||
const int kart_amount = (int)m_karts.size();
|
||||
for (int i = 0 ; i < kart_amount; ++i)
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ Event::Event(ENetEvent* event)
|
||||
m_peer = NULL;
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
{
|
||||
if (peers[i]->m_peer == event->peer)
|
||||
if (peers[i]->m_enet_peer == event->peer)
|
||||
{
|
||||
m_peer = peers[i];
|
||||
Log::verbose("Event", "The peer you sought has been found on %p",
|
||||
@ -73,7 +73,7 @@ Event::Event(ENetEvent* event)
|
||||
if (m_peer == NULL) // peer does not exist, create him
|
||||
{
|
||||
STKPeer* new_peer = new STKPeer();
|
||||
new_peer->m_peer = event->peer;
|
||||
new_peer->m_enet_peer = event->peer;
|
||||
m_peer = new_peer;
|
||||
Log::debug("Event",
|
||||
"Creating a new peer, address are STKPeer:%p, Peer:%p",
|
||||
@ -81,18 +81,6 @@ Event::Event(ENetEvent* event)
|
||||
}
|
||||
} // Event(ENetEvent)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Constructor
|
||||
* \param event : The event to copy.
|
||||
*/
|
||||
Event::Event(const Event& event)
|
||||
{
|
||||
m_type = event.m_type;
|
||||
m_packet = NULL;
|
||||
m_data = event.m_data;
|
||||
m_peer = event.m_peer;
|
||||
} // Event(Event)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Destructor that frees the memory of the package.
|
||||
*/
|
||||
|
@ -24,10 +24,14 @@
|
||||
#ifndef EVENT_HPP
|
||||
#define EVENT_HPP
|
||||
|
||||
#include "network/stk_peer.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
#include "enet/enet.h"
|
||||
|
||||
class STKPeer;
|
||||
|
||||
/*!
|
||||
* \enum EVENT_TYPE
|
||||
* \brief Represents a network event type.
|
||||
@ -52,6 +56,7 @@ enum EVENT_TYPE
|
||||
class Event
|
||||
{
|
||||
private:
|
||||
LEAK_CHECK()
|
||||
/** Copy of the data passed by the event. */
|
||||
NetworkString m_data;
|
||||
|
||||
@ -66,7 +71,6 @@ private:
|
||||
|
||||
public:
|
||||
Event(ENetEvent* event);
|
||||
Event(const Event& event);
|
||||
~Event();
|
||||
void removeFront(int size);
|
||||
|
||||
@ -78,11 +82,16 @@ public:
|
||||
/** Returns the peer of this event. */
|
||||
STKPeer* getPeer() const { return m_peer; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Get a copy of the data.
|
||||
* \return A copy of the message data. This is empty for events like
|
||||
/** \brief Get a const reference to the received data.
|
||||
* This is empty for events like connection or disconnections.
|
||||
*/
|
||||
const NetworkString& data() const { return m_data; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Get a non-const reference to the received data.
|
||||
* A copy of the message data. This is empty for events like
|
||||
* connection or disconnections. */
|
||||
NetworkString data() const { return m_data; }
|
||||
|
||||
NetworkString& data() { return m_data; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
}; // class Event
|
||||
|
||||
|
@ -18,14 +18,9 @@
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
|
||||
#include "network/protocols/hide_public_address.hpp"
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
|
||||
#include "network/event.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/client_network_manager.hpp"
|
||||
#include "network/server_network_manager.hpp"
|
||||
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <pthread.h>
|
||||
@ -58,6 +53,8 @@ NetworkManager::~NetworkManager()
|
||||
} // ~Networkmanager
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** \brief Function to start the Network Manager (start threads).
|
||||
*/
|
||||
void NetworkManager::run()
|
||||
{
|
||||
// create the protocol manager
|
||||
@ -65,6 +62,9 @@ void NetworkManager::run()
|
||||
} // run
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** \brief Function to reset the Network Manager.
|
||||
* This function resets the peers and the listening host.
|
||||
*/
|
||||
void NetworkManager::reset()
|
||||
{
|
||||
if (m_localhost)
|
||||
@ -78,6 +78,10 @@ void NetworkManager::reset()
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** \brief Function that aborts the NetworkManager.
|
||||
* This function will stop the listening, delete the host and stop
|
||||
* threads that are related to networking.
|
||||
*/
|
||||
void NetworkManager::abort()
|
||||
{
|
||||
m_localhost->stopListening();
|
||||
@ -88,17 +92,25 @@ void NetworkManager::abort()
|
||||
} // abort
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool NetworkManager::connect(const TransportAddress& peer)
|
||||
/** \brief Try to establish a connection to a given transport address.
|
||||
* \param peer : The transport address which you want to connect to.
|
||||
* \return True if we're successfully connected. False elseway.
|
||||
*/
|
||||
bool NetworkManager::connect(const TransportAddress& address)
|
||||
{
|
||||
if (peerExists(peer))
|
||||
return isConnectedTo(peer);
|
||||
if (peerExists(address))
|
||||
return isConnectedTo(address);
|
||||
|
||||
return STKPeer::connectToHost(m_localhost, peer, 2, 0);
|
||||
return STKPeer::connectToHost(m_localhost, address, 2, 0);
|
||||
} // connect
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** \brief Changes the socket working mode.
|
||||
* Sockets can be in two modes : The ENet mode and a mode we will call
|
||||
* the 'Raw' mode. In the ENet mode, the socket will be read as
|
||||
* \param peer : The transport address which you want to connect to.
|
||||
* \return True if we're successfully connected. False elseway.
|
||||
*/
|
||||
void NetworkManager::setManualSocketsMode(bool manual)
|
||||
{
|
||||
if (manual)
|
||||
@ -108,7 +120,13 @@ void NetworkManager::setManualSocketsMode(bool manual)
|
||||
} // setManualSocketsMode
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NetworkManager::notifyEvent(Event* event)
|
||||
/** Is called from STKHost when an event (i.e. a package) is received. If the
|
||||
* event indicates a new connection, the peer is added to the list of peers.
|
||||
* It logs the package, and propagates the event to the ProtocollManager,
|
||||
* which in turn will notify individual protocols.
|
||||
* \param event Pointer to the event to propagate.
|
||||
*/
|
||||
void NetworkManager::propagateEvent(Event* event)
|
||||
{
|
||||
Log::verbose("NetworkManager", "EVENT received of type %d",
|
||||
(int)(event->getType()));
|
||||
@ -135,8 +153,8 @@ void NetworkManager::notifyEvent(Event* event)
|
||||
}
|
||||
|
||||
// notify for the event now.
|
||||
ProtocolManager::getInstance()->notifyEvent(event);
|
||||
} // notifyEvent
|
||||
ProtocolManager::getInstance()->propagateEvent(event);
|
||||
} // propagateEvent
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -163,18 +181,20 @@ void NetworkManager::sendPacketExcept(STKPeer* peer, const NetworkString& data,
|
||||
} // sendPacketExcept
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** A previous GameSetup is deletea and a new one is created.
|
||||
* \return Newly create GameSetup object.
|
||||
*/
|
||||
GameSetup* NetworkManager::setupNewGame()
|
||||
{
|
||||
if (m_game_setup)
|
||||
delete m_game_setup;
|
||||
m_game_setup = NULL;
|
||||
m_game_setup = new GameSetup();
|
||||
return m_game_setup;
|
||||
} // setupNewGame
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Called when you leave a server.
|
||||
*/
|
||||
void NetworkManager::disconnected()
|
||||
{
|
||||
// delete the game setup
|
||||
@ -248,15 +268,3 @@ void NetworkManager::removePeer(STKPeer* peer)
|
||||
} // removePeer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool NetworkManager::peerExists(const TransportAddress& peer)
|
||||
{
|
||||
return m_localhost->peerExists(peer);
|
||||
} // peerExists
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool NetworkManager::isConnectedTo(const TransportAddress& peer)
|
||||
{
|
||||
return m_localhost->isConnectedTo(peer);
|
||||
} // isConnectedTo
|
||||
|
@ -28,13 +28,14 @@
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/types.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include "utils/singleton.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Event;
|
||||
class GameSetup;
|
||||
|
||||
/** \class NetworkManager
|
||||
* \brief Gives the general functions to use network communication.
|
||||
* This class is in charge of storing the peers connected to this host.
|
||||
@ -46,98 +47,93 @@
|
||||
*/
|
||||
class NetworkManager : public AbstractSingleton<NetworkManager>
|
||||
{
|
||||
protected:
|
||||
NetworkManager();
|
||||
virtual ~NetworkManager();
|
||||
|
||||
/** Pointer to the one stk host instance, which is used to do all
|
||||
* network communication. */
|
||||
STKHost* m_localhost;
|
||||
|
||||
/** The list of peers connected to this instance. */
|
||||
std::vector<STKPeer*> m_peers;
|
||||
|
||||
private:
|
||||
GameSetup* m_game_setup;
|
||||
|
||||
/** This computer's public IP address. With lock since it can
|
||||
* be updated from a separate thread. */
|
||||
Synchronised<TransportAddress> m_public_address;
|
||||
|
||||
PlayerLogin m_player_login;
|
||||
|
||||
|
||||
friend class AbstractSingleton<NetworkManager>;
|
||||
public:
|
||||
/** \brief Function to start the Network Manager (start threads) */
|
||||
virtual void run();
|
||||
/** \brief Function to reset the Network Manager.
|
||||
* This function resets the peers and the listening host.
|
||||
*/
|
||||
virtual void reset();
|
||||
/** \brief Function that aborts the NetworkManager.
|
||||
* This function will stop the listening, delete the host and stop
|
||||
* threads that are related to networking.
|
||||
*/
|
||||
virtual void abort();
|
||||
public:
|
||||
virtual void run();
|
||||
virtual void reset();
|
||||
virtual void abort();
|
||||
virtual bool connect(const TransportAddress& peer);
|
||||
virtual void setManualSocketsMode(bool manual);
|
||||
virtual void propagateEvent(Event* event);
|
||||
virtual void sendPacket(const NetworkString& data,
|
||||
bool reliable = true) = 0;
|
||||
virtual void sendPacket(STKPeer* peer,
|
||||
const NetworkString& data,
|
||||
bool reliable = true);
|
||||
virtual void sendPacketExcept(STKPeer* peer,
|
||||
const NetworkString& data,
|
||||
bool reliable = true);
|
||||
|
||||
// network management functions
|
||||
/** \brief Try to establish a connection to a given transport address.
|
||||
* \param peer : The transport address which you want to connect to.
|
||||
* \return True if we're successfully connected. False elseway.
|
||||
*/
|
||||
virtual bool connect(const TransportAddress& peer);
|
||||
/** \brief Changes the socket working mode.
|
||||
* Sockets can be in two modes : The ENet mode and a mode we will call
|
||||
* the 'Raw' mode. In the ENet mode, the socket will be read as
|
||||
* \param peer : The transport address which you want to connect to.
|
||||
* \return True if we're successfully connected. False elseway.
|
||||
*/
|
||||
virtual void setManualSocketsMode(bool manual);
|
||||
// Game related functions
|
||||
virtual GameSetup* setupNewGame();
|
||||
virtual void disconnected();
|
||||
virtual bool isServer() = 0;
|
||||
|
||||
// message/packets related functions
|
||||
virtual void notifyEvent(Event* event);
|
||||
virtual void sendPacket(const NetworkString& data,
|
||||
bool reliable = true) = 0;
|
||||
virtual void sendPacket(STKPeer* peer,
|
||||
const NetworkString& data,
|
||||
bool reliable = true);
|
||||
virtual void sendPacketExcept(STKPeer* peer,
|
||||
const NetworkString& data,
|
||||
bool reliable = true);
|
||||
// raw data management
|
||||
void setLogin(std::string username, std::string password);
|
||||
void setPublicAddress(const TransportAddress& addr);
|
||||
void removePeer(STKPeer* peer);
|
||||
|
||||
// Game related functions
|
||||
virtual GameSetup* setupNewGame(); //!< Creates a new game setup and returns it
|
||||
virtual void disconnected(); //!< Called when you leave a server
|
||||
// getters
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if a peer from the specified IP:port address
|
||||
* already exists. */
|
||||
virtual bool peerExists(const TransportAddress& peer)
|
||||
{
|
||||
return m_localhost->peerExists(peer);
|
||||
} // peerExists
|
||||
// --------------------------------------------------------------------
|
||||
virtual bool isConnectedTo(const TransportAddress& peer)
|
||||
{
|
||||
return m_localhost->isConnectedTo(peer);
|
||||
} // isConnectedTo
|
||||
|
||||
// raw data management
|
||||
void setLogin(std::string username, std::string password);
|
||||
void setPublicAddress(const TransportAddress& addr);
|
||||
void removePeer(STKPeer* peer);
|
||||
// --------------------------------------------------------------------
|
||||
inline bool isClient() { return !isServer(); }
|
||||
// --------------------------------------------------------------------
|
||||
STKHost* getHost() { return m_localhost; }
|
||||
// --------------------------------------------------------------------
|
||||
std::vector<STKPeer*> getPeers() { return m_peers; }
|
||||
// --------------------------------------------------------------------
|
||||
unsigned int getPeerCount() { return (int)m_peers.size(); }
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the public IP address (thread safe). The network manager
|
||||
* is a friend of TransportAddress and so has access to the copy
|
||||
* constructor, which is otherwise declared private. */
|
||||
const TransportAddress getPublicAddress()
|
||||
{
|
||||
m_public_address.lock();
|
||||
TransportAddress a;
|
||||
a.copy(m_public_address.getData());
|
||||
m_public_address.unlock();
|
||||
return a;
|
||||
} // getPublicAddress
|
||||
|
||||
// getters
|
||||
virtual bool peerExists(const TransportAddress& peer);
|
||||
virtual bool isConnectedTo(const TransportAddress& peer);
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the current game setup. */
|
||||
GameSetup* getGameSetup() { return m_game_setup; }
|
||||
|
||||
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; }
|
||||
// --------------------------------------------------------------------
|
||||
unsigned int getPeerCount() { return (int)m_peers.size(); }
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the public IP address (thread safe). The network manager
|
||||
* is a friend of TransportAddress and so has access to the copy
|
||||
* constructor, which is otherwise declared private. */
|
||||
const TransportAddress getPublicAddress()
|
||||
{
|
||||
m_public_address.lock();
|
||||
TransportAddress a;
|
||||
a.copy(m_public_address.getData());
|
||||
m_public_address.unlock();
|
||||
return a;
|
||||
} // getPublicAddress
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
GameSetup* getGameSetup() { return m_game_setup; }
|
||||
|
||||
protected:
|
||||
NetworkManager();
|
||||
virtual ~NetworkManager();
|
||||
|
||||
// protected members
|
||||
std::vector<STKPeer*> m_peers;
|
||||
STKHost* m_localhost;
|
||||
bool m_playing_online;
|
||||
GameSetup* m_game_setup;
|
||||
/** This computer's public IP address. With lock since it can
|
||||
* be updated from a separate thread. */
|
||||
Synchronised<TransportAddress> m_public_address;
|
||||
PlayerLogin m_player_login;
|
||||
};
|
||||
}; // class NetworkManager
|
||||
|
||||
#endif // NETWORKMANAGER_HPP
|
||||
|
@ -39,10 +39,11 @@ typedef unsigned char uchar;
|
||||
class NetworkString
|
||||
{
|
||||
private:
|
||||
union {
|
||||
union FloatAsInt
|
||||
{
|
||||
float f;
|
||||
uint8_t i[4];
|
||||
} f_as_i; // float as integer
|
||||
}; // float as integer
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
union {
|
||||
@ -165,6 +166,7 @@ public:
|
||||
NetworkString& addFloat(const float& value) //!< BEWARE OF PRECISION
|
||||
{
|
||||
assert(sizeof(float) == 4);
|
||||
FloatAsInt f_as_i;
|
||||
f_as_i.f = value;
|
||||
m_string.push_back(f_as_i.i[0]);
|
||||
m_string.push_back(f_as_i.i[1]);
|
||||
@ -339,8 +341,9 @@ public:
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a 4-byte floating point value. */
|
||||
float getFloat(int pos = 0) //!< BEWARE OF PRECISION
|
||||
float getFloat(int pos = 0) const //!< BEWARE OF PRECISION
|
||||
{
|
||||
FloatAsInt f_as_i;
|
||||
for (int i = 0; i < 4; i++)
|
||||
f_as_i.i[i] = m_string[pos + i];
|
||||
return f_as_i.f;
|
||||
@ -426,6 +429,7 @@ public:
|
||||
/** Get and remove a 4 byte floating point value. */
|
||||
float getAndRemoveFloat(int pos = 0) //!< BEWARE OF PRECISION
|
||||
{
|
||||
FloatAsInt f_as_i;
|
||||
for (int i = 0; i < 4; i++)
|
||||
f_as_i.i[i] = m_string[pos + i];
|
||||
return f_as_i.f;
|
||||
|
@ -18,10 +18,11 @@
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
|
||||
Protocol::Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type)
|
||||
Protocol::Protocol(CallbackObject* callback_object, ProtocolType type)
|
||||
{
|
||||
m_callback_object = callback_object;
|
||||
m_type = type;
|
||||
@ -49,14 +50,14 @@ void Protocol::setListener(ProtocolManager* listener)
|
||||
m_listener = listener;
|
||||
}
|
||||
|
||||
PROTOCOL_TYPE Protocol::getProtocolType()
|
||||
ProtocolType Protocol::getProtocolType()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
bool Protocol::checkDataSizeAndToken(Event* event, int minimum_size)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() < minimum_size || data[0] != 4)
|
||||
{
|
||||
Log::warn("Protocol", "Receiving a badly "
|
||||
@ -77,7 +78,7 @@ bool Protocol::checkDataSizeAndToken(Event* event, int minimum_size)
|
||||
|
||||
bool Protocol::isByteCorrect(Event* event, int byte_nb, int value)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data[byte_nb] != value)
|
||||
{
|
||||
Log::info("Protocol", "Bad byte at pos %d. %d "
|
||||
|
@ -23,17 +23,18 @@
|
||||
#ifndef PROTOCOL_HPP
|
||||
#define PROTOCOL_HPP
|
||||
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/types.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
class Event;
|
||||
class ProtocolManager;
|
||||
|
||||
/** \enum PROTOCOL_TYPE
|
||||
/** \enum ProtocolType
|
||||
* \brief The types that protocols can have. This is used to select which protocol receives which event.
|
||||
* \ingroup network
|
||||
*/
|
||||
enum PROTOCOL_TYPE
|
||||
enum ProtocolType
|
||||
{
|
||||
PROTOCOL_NONE = 0, //!< No protocol type assigned.
|
||||
PROTOCOL_CONNECTION = 1, //!< Protocol that deals with client-server connection.
|
||||
@ -64,7 +65,7 @@ class Protocol
|
||||
* \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);
|
||||
Protocol(CallbackObject* callback_object, ProtocolType type);
|
||||
/*! \brief Destructor
|
||||
*/
|
||||
virtual ~Protocol();
|
||||
@ -111,7 +112,7 @@ class Protocol
|
||||
/*! \brief Method to get a protocol's type.
|
||||
* \return The protocol type.
|
||||
*/
|
||||
PROTOCOL_TYPE getProtocolType();
|
||||
ProtocolType getProtocolType();
|
||||
|
||||
/// functions to check incoming data easily
|
||||
bool checkDataSizeAndToken(Event* event, int minimum_size);
|
||||
@ -121,7 +122,7 @@ class Protocol
|
||||
|
||||
protected:
|
||||
ProtocolManager* m_listener; //!< The protocol listener
|
||||
PROTOCOL_TYPE m_type; //!< The type of the protocol
|
||||
ProtocolType m_type; //!< The type of the protocol
|
||||
CallbackObject* m_callback_object; //!< The callback object, if needed
|
||||
};
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocol.hpp"
|
||||
#include "utils/log.hpp"
|
||||
@ -66,6 +67,8 @@ ProtocolManager::~ProtocolManager()
|
||||
} // ~ProtocolManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Stops the protocol manager.
|
||||
*/
|
||||
void ProtocolManager::abort()
|
||||
{
|
||||
pthread_mutex_unlock(&m_exit_mutex); // will stop the update function
|
||||
@ -76,9 +79,9 @@ void ProtocolManager::abort()
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
pthread_mutex_lock(&m_id_mutex);
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size() ; i++)
|
||||
delete m_protocols.getData()[i].protocol;
|
||||
delete m_protocols.getData()[i].m_protocol;
|
||||
for (unsigned int i = 0; i < m_events_to_process.getData().size() ; i++)
|
||||
delete m_events_to_process.getData()[i].event;
|
||||
delete m_events_to_process.getData()[i].m_event;
|
||||
m_protocols.getData().clear();
|
||||
m_requests.clear();
|
||||
m_events_to_process.getData().clear();
|
||||
@ -95,63 +98,76 @@ void ProtocolManager::abort()
|
||||
} // abort
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::notifyEvent(Event* event)
|
||||
/** \brief Function that processes incoming events.
|
||||
* This function is called by the network manager each time there is an
|
||||
* incoming packet.
|
||||
*/
|
||||
void ProtocolManager::propagateEvent(Event* event)
|
||||
{
|
||||
m_events_to_process.lock();
|
||||
Event* event2 = new Event(*event);
|
||||
|
||||
// register protocols that will receive this event
|
||||
std::vector<unsigned int> protocols_ids;
|
||||
PROTOCOL_TYPE searched_protocol = PROTOCOL_NONE;
|
||||
ProtocolType searched_protocol = PROTOCOL_NONE;
|
||||
if (event->getType() == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
if (event2->data().size() > 0)
|
||||
if (event->data().size() > 0)
|
||||
{
|
||||
searched_protocol = (PROTOCOL_TYPE)(event2->data()[0]);
|
||||
event2->removeFront(1);
|
||||
searched_protocol = (ProtocolType)(event->data()[0]);
|
||||
event->removeFront(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("ProtocolManager", "Not enough data.");
|
||||
}
|
||||
}
|
||||
if (event->getType() == EVENT_TYPE_CONNECTED)
|
||||
else if (event->getType() == EVENT_TYPE_CONNECTED)
|
||||
{
|
||||
searched_protocol = PROTOCOL_CONNECTION;
|
||||
}
|
||||
Log::verbose("ProtocolManager", "Received event for protocols of type %d",
|
||||
searched_protocol);
|
||||
|
||||
std::vector<unsigned int> protocols_ids;
|
||||
m_protocols.lock();
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size() ; i++)
|
||||
{
|
||||
const ProtocolInfo &pi = m_protocols.getData()[i];
|
||||
// Pass data to protocols even when paused
|
||||
if (m_protocols.getData()[i].protocol->getProtocolType() == searched_protocol ||
|
||||
if (pi.m_protocol->getProtocolType() == searched_protocol ||
|
||||
event->getType() == EVENT_TYPE_DISCONNECTED)
|
||||
{
|
||||
protocols_ids.push_back(m_protocols.getData()[i].id);
|
||||
protocols_ids.push_back(pi.m_id);
|
||||
}
|
||||
}
|
||||
} // for i in m_protocols
|
||||
m_protocols.unlock();
|
||||
|
||||
// no protocol was aimed, show the msg to debug
|
||||
if (searched_protocol == PROTOCOL_NONE)
|
||||
{
|
||||
Log::debug("ProtocolManager", "NO PROTOCOL : Message is \"%s\"",
|
||||
event2->data().std_string().c_str());
|
||||
event->data().std_string().c_str());
|
||||
}
|
||||
|
||||
if (protocols_ids.size() != 0)
|
||||
{
|
||||
EventProcessingInfo epi;
|
||||
epi.arrival_time = (double)StkTime::getTimeSinceEpoch();
|
||||
epi.event = event2;
|
||||
epi.protocols_ids = protocols_ids;
|
||||
m_events_to_process.getData().push_back(epi); // add the event to the queue
|
||||
epi.m_arrival_time = (double)StkTime::getTimeSinceEpoch();
|
||||
epi.m_event = event;
|
||||
epi.m_protocols_ids = protocols_ids;
|
||||
// Add the event to the queue. After the event is handled
|
||||
// its memory will be freed.
|
||||
m_events_to_process.getData().push_back(epi);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("ProtocolManager",
|
||||
"Received an event for %d that has no destination protocol.",
|
||||
searched_protocol);
|
||||
m_events_to_process.lock();
|
||||
} // notifyEvent
|
||||
// Free the memory for the vent
|
||||
delete event;
|
||||
}
|
||||
m_events_to_process.unlock();
|
||||
} // propagateEvent
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::sendMessage(Protocol* sender, const NetworkString& message,
|
||||
@ -185,33 +201,42 @@ void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer,
|
||||
} // sendMessageExcept
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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.
|
||||
*/
|
||||
uint32_t ProtocolManager::requestStart(Protocol* protocol)
|
||||
{
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
ProtocolInfo info;
|
||||
info.protocol = protocol;
|
||||
info.state = PROTOCOL_STATE_RUNNING;
|
||||
assignProtocolId(&info); // assign a unique id to the protocol.
|
||||
req.protocol_info = info;
|
||||
req.type = PROTOCOL_REQUEST_START;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_protocol_info.m_state = PROTOCOL_STATE_INITIALISING;
|
||||
assignProtocolId(&req.m_protocol_info); // assign a unique id to the protocol.
|
||||
req.m_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;
|
||||
return req.m_protocol_info.m_id;
|
||||
} // requestStart
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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
|
||||
*/
|
||||
void ProtocolManager::requestStop(Protocol* protocol)
|
||||
{
|
||||
if (!protocol)
|
||||
return;
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
req.protocol_info.protocol = protocol;
|
||||
req.type = PROTOCOL_REQUEST_STOP;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_type = PROTOCOL_REQUEST_STOP;
|
||||
// add it to the request stack
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
@ -219,14 +244,19 @@ void ProtocolManager::requestStop(Protocol* protocol)
|
||||
} // requestStop
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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
|
||||
*/
|
||||
void ProtocolManager::requestPause(Protocol* protocol)
|
||||
{
|
||||
if (!protocol)
|
||||
return;
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
req.protocol_info.protocol = protocol;
|
||||
req.type = PROTOCOL_REQUEST_PAUSE;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_type = PROTOCOL_REQUEST_PAUSE;
|
||||
// add it to the request stack
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
@ -234,14 +264,19 @@ void ProtocolManager::requestPause(Protocol* protocol)
|
||||
} // requestPause
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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
|
||||
*/
|
||||
void ProtocolManager::requestUnpause(Protocol* protocol)
|
||||
{
|
||||
if (!protocol)
|
||||
return;
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
req.protocol_info.protocol = protocol;
|
||||
req.type = PROTOCOL_REQUEST_UNPAUSE;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_type = PROTOCOL_REQUEST_UNPAUSE;
|
||||
// add it to the request stack
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
@ -249,20 +284,25 @@ void ProtocolManager::requestUnpause(Protocol* protocol)
|
||||
} // requestUnpause
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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
|
||||
*/
|
||||
void ProtocolManager::requestTerminate(Protocol* protocol)
|
||||
{
|
||||
if (!protocol)
|
||||
return;
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
req.protocol_info.protocol = protocol;
|
||||
req.type = PROTOCOL_REQUEST_TERMINATE;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_type = PROTOCOL_REQUEST_TERMINATE;
|
||||
// add it to the request stack
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
// check that the request does not already exist :
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
if (m_requests[i].protocol_info.protocol == protocol)
|
||||
if (m_requests[i].m_protocol_info.m_protocol == protocol)
|
||||
{
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
return;
|
||||
@ -273,19 +313,25 @@ void ProtocolManager::requestTerminate(Protocol* protocol)
|
||||
} // requestTerminate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::startProtocol(ProtocolInfo protocol)
|
||||
/** \brief Starts a protocol.
|
||||
* Add the protocol info to the m_protocols vector.
|
||||
* \param protocol : ProtocolInfo to start.
|
||||
*/
|
||||
void ProtocolManager::startProtocol(ProtocolInfo &protocol)
|
||||
{
|
||||
assert(protocol.m_state == PROTOCOL_STATE_INITIALISING);
|
||||
// add the protocol to the protocol vector so that it's updated
|
||||
m_protocols.lock();
|
||||
pthread_mutex_lock(&m_asynchronous_protocols_mutex);
|
||||
Log::info("ProtocolManager",
|
||||
"A %s protocol with id=%u has been started. There are %ld protocols running.",
|
||||
typeid(*protocol.protocol).name(), protocol.id,
|
||||
typeid(*protocol.m_protocol).name(), protocol.m_id,
|
||||
m_protocols.getData().size()+1);
|
||||
m_protocols.getData().push_back(protocol);
|
||||
// setup the protocol and notify it that it's started
|
||||
protocol.protocol->setListener(this);
|
||||
protocol.protocol->setup();
|
||||
protocol.m_protocol->setListener(this);
|
||||
protocol.m_protocol->setup();
|
||||
protocol.m_state = PROTOCOL_STATE_RUNNING;
|
||||
m_protocols.unlock();
|
||||
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
|
||||
} // startProtocol
|
||||
@ -301,12 +347,12 @@ void ProtocolManager::pauseProtocol(ProtocolInfo protocol)
|
||||
// FIXME Does this need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
ProtocolInfo &p = m_protocols.getData()[i];
|
||||
if (p.protocol == protocol.protocol &&
|
||||
p.state == PROTOCOL_STATE_RUNNING)
|
||||
ProtocolInfo &pi = m_protocols.getData()[i];
|
||||
if (pi.m_protocol == protocol.m_protocol &&
|
||||
pi.m_state == PROTOCOL_STATE_RUNNING)
|
||||
{
|
||||
p.state = PROTOCOL_STATE_PAUSED;
|
||||
p.protocol->pause();
|
||||
pi.m_state = PROTOCOL_STATE_PAUSED;
|
||||
pi.m_protocol->pause();
|
||||
}
|
||||
}
|
||||
} // pauseProtocol
|
||||
@ -318,11 +364,11 @@ void ProtocolManager::unpauseProtocol(ProtocolInfo protocol)
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
ProtocolInfo &p = m_protocols.getData()[i];
|
||||
if (p.protocol == protocol.protocol &&
|
||||
p.state == PROTOCOL_STATE_PAUSED)
|
||||
if (p.m_protocol == protocol.m_protocol &&
|
||||
p.m_state == PROTOCOL_STATE_PAUSED)
|
||||
{
|
||||
p.state = PROTOCOL_STATE_RUNNING;
|
||||
p.protocol->unpause();
|
||||
p.m_state = PROTOCOL_STATE_RUNNING;
|
||||
p.m_protocol->unpause();
|
||||
}
|
||||
}
|
||||
} // unpauseProtocol
|
||||
@ -334,12 +380,12 @@ void ProtocolManager::protocolTerminated(ProtocolInfo protocol)
|
||||
m_protocols.lock();
|
||||
pthread_mutex_lock(&m_asynchronous_protocols_mutex);
|
||||
int offset = 0;
|
||||
std::string protocol_type = typeid(*protocol.protocol).name();
|
||||
std::string protocol_type = typeid(*protocol.m_protocol).name();
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i-offset].protocol == protocol.protocol)
|
||||
if (m_protocols.getData()[i-offset].m_protocol == protocol.m_protocol)
|
||||
{
|
||||
delete m_protocols.getData()[i].protocol;
|
||||
delete m_protocols.getData()[i].m_protocol;
|
||||
m_protocols.getData().erase(m_protocols.getData().begin()+(i-offset),
|
||||
m_protocols.getData().begin()+(i-offset)+1);
|
||||
offset++;
|
||||
@ -353,46 +399,59 @@ void ProtocolManager::protocolTerminated(ProtocolInfo protocol)
|
||||
} // protocolTerminated
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool ProtocolManager::propagateEvent(EventProcessingInfo* event, bool synchronous)
|
||||
/** Sends the event to the corresponding protocol.
|
||||
*/
|
||||
bool ProtocolManager::sendEvent(EventProcessingInfo* event, bool synchronous)
|
||||
{
|
||||
m_protocols.lock();
|
||||
int index = 0;
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (event->protocols_ids[index] == m_protocols.getData()[i].id)
|
||||
if (event->m_protocols_ids[index] == m_protocols.getData()[i].m_id)
|
||||
{
|
||||
bool result = false;
|
||||
if (synchronous)
|
||||
result = m_protocols.getData()[i].protocol
|
||||
->notifyEvent(event->event);
|
||||
result = m_protocols.getData()[i].m_protocol
|
||||
->notifyEvent(event->m_event);
|
||||
else
|
||||
result = m_protocols.getData()[i].protocol
|
||||
->notifyEventAsynchronous(event->event);
|
||||
result = m_protocols.getData()[i].m_protocol
|
||||
->notifyEventAsynchronous(event->m_event);
|
||||
if (result)
|
||||
event->protocols_ids.pop_back();
|
||||
event->m_protocols_ids.pop_back();
|
||||
else
|
||||
index++;
|
||||
}
|
||||
}
|
||||
if (event->protocols_ids.size() == 0 ||
|
||||
(StkTime::getTimeSinceEpoch()-event->arrival_time) >= TIME_TO_KEEP_EVENTS)
|
||||
m_protocols.unlock();
|
||||
|
||||
if (event->m_protocols_ids.size() == 0 ||
|
||||
(StkTime::getTimeSinceEpoch()-event->m_arrival_time) >= TIME_TO_KEEP_EVENTS)
|
||||
{
|
||||
// because we made a copy of the event
|
||||
delete event->event;
|
||||
delete event->m_event;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} // propagateEvent
|
||||
} // sendEvent
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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 the main loop.
|
||||
* This function IS FPS-dependant.
|
||||
*/
|
||||
void ProtocolManager::update()
|
||||
{
|
||||
// before updating, notice protocols that they have received events
|
||||
// before updating, notify protocols that they have received events
|
||||
m_events_to_process.lock();
|
||||
int size = (int)m_events_to_process.getData().size();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
bool result = propagateEvent(&m_events_to_process.getData()[i+offset], true);
|
||||
bool result = sendEvent(&m_events_to_process.getData()[i+offset], true);
|
||||
if (result)
|
||||
{
|
||||
m_events_to_process.getData()
|
||||
@ -406,13 +465,21 @@ void ProtocolManager::update()
|
||||
m_protocols.lock();
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i].protocol->update();
|
||||
if (m_protocols.getData()[i].m_state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i].m_protocol->update();
|
||||
}
|
||||
m_protocols.unlock();
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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 in a thread.
|
||||
* This function IS NOT FPS-dependant.
|
||||
*/
|
||||
void ProtocolManager::asynchronousUpdate()
|
||||
{
|
||||
// before updating, notice protocols that they have received information
|
||||
@ -421,7 +488,7 @@ void ProtocolManager::asynchronousUpdate()
|
||||
int offset = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
bool result = propagateEvent(&m_events_to_process.getData()[i+offset], false);
|
||||
bool result = sendEvent(&m_events_to_process.getData()[i+offset], false);
|
||||
if (result)
|
||||
{
|
||||
m_events_to_process.getData()
|
||||
@ -437,8 +504,8 @@ void ProtocolManager::asynchronousUpdate()
|
||||
// FIXME: does m_protocols need to be locked???
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i].protocol->asynchronousUpdate();
|
||||
if (m_protocols.getData()[i].m_state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i].m_protocol->asynchronousUpdate();
|
||||
}
|
||||
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
|
||||
|
||||
@ -447,22 +514,22 @@ void ProtocolManager::asynchronousUpdate()
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
switch (m_requests[i].type)
|
||||
switch (m_requests[i].m_type)
|
||||
{
|
||||
case PROTOCOL_REQUEST_START:
|
||||
startProtocol(m_requests[i].protocol_info);
|
||||
startProtocol(m_requests[i].m_protocol_info);
|
||||
break;
|
||||
case PROTOCOL_REQUEST_STOP:
|
||||
stopProtocol(m_requests[i].protocol_info);
|
||||
stopProtocol(m_requests[i].m_protocol_info);
|
||||
break;
|
||||
case PROTOCOL_REQUEST_PAUSE:
|
||||
pauseProtocol(m_requests[i].protocol_info);
|
||||
pauseProtocol(m_requests[i].m_protocol_info);
|
||||
break;
|
||||
case PROTOCOL_REQUEST_UNPAUSE:
|
||||
unpauseProtocol(m_requests[i].protocol_info);
|
||||
unpauseProtocol(m_requests[i].m_protocol_info);
|
||||
break;
|
||||
case PROTOCOL_REQUEST_TERMINATE:
|
||||
protocolTerminated(m_requests[i].protocol_info);
|
||||
protocolTerminated(m_requests[i].m_protocol_info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -471,38 +538,46 @@ void ProtocolManager::asynchronousUpdate()
|
||||
} // asynchronousUpdate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
PROTOCOL_STATE ProtocolManager::getProtocolState(uint32_t id)
|
||||
/** \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.
|
||||
*/
|
||||
ProtocolState ProtocolManager::getProtocolState(uint32_t id)
|
||||
{
|
||||
//FIXME that actually need a lock, but it also can be called from
|
||||
// a locked section anyway
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].id == id) // we know a protocol with that id
|
||||
return m_protocols.getData()[i].state;
|
||||
if (m_protocols.getData()[i].m_id == id) // we know a protocol with that id
|
||||
return m_protocols.getData()[i].m_state;
|
||||
}
|
||||
// the protocol isn't running right now
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
// the protocol is going to be started
|
||||
if (m_requests[i].protocol_info.id == id)
|
||||
if (m_requests[i].m_protocol_info.m_id == id)
|
||||
return PROTOCOL_STATE_RUNNING; // we can say it's running
|
||||
}
|
||||
return PROTOCOL_STATE_TERMINATED; // else, it's already finished
|
||||
} // getProtocolState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
PROTOCOL_STATE ProtocolManager::getProtocolState(Protocol* protocol)
|
||||
/** \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.
|
||||
*/
|
||||
ProtocolState ProtocolManager::getProtocolState(Protocol* protocol)
|
||||
{
|
||||
// FIXME Does this need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].protocol == protocol) // the protocol is known
|
||||
return m_protocols.getData()[i].state;
|
||||
if (m_protocols.getData()[i].m_protocol == protocol) // the protocol is known
|
||||
return m_protocols.getData()[i].m_state;
|
||||
}
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
// the protocol is going to be started
|
||||
if (m_requests[i].protocol_info.protocol == protocol)
|
||||
if (m_requests[i].m_protocol_info.m_protocol == protocol)
|
||||
return PROTOCOL_STATE_RUNNING; // we can say it's running
|
||||
}
|
||||
// we don't know this protocol at all, it's finished
|
||||
@ -510,48 +585,65 @@ PROTOCOL_STATE ProtocolManager::getProtocolState(Protocol* protocol)
|
||||
} // getProtocolState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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.
|
||||
*/
|
||||
uint32_t ProtocolManager::getProtocolID(Protocol* protocol)
|
||||
{
|
||||
// FIXME: Does this need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].protocol == protocol)
|
||||
return m_protocols.getData()[i].id;
|
||||
if (m_protocols.getData()[i].m_protocol == protocol)
|
||||
return m_protocols.getData()[i].m_id;
|
||||
}
|
||||
return 0;
|
||||
} // getProtocolID
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Get a protocol using its id.
|
||||
* \param id : Unique ID of the seek protocol.
|
||||
* \return The protocol that has the ID id.
|
||||
*/
|
||||
Protocol* ProtocolManager::getProtocol(uint32_t id)
|
||||
{
|
||||
// FIXME: does m_protocols need to be locked??
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].id == id)
|
||||
return m_protocols.getData()[i].protocol;
|
||||
if (m_protocols.getData()[i].m_id == id)
|
||||
return m_protocols.getData()[i].m_protocol;
|
||||
}
|
||||
return NULL;
|
||||
} // getProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
Protocol* ProtocolManager::getProtocol(PROTOCOL_TYPE type)
|
||||
/** \brief Get a protocol using its type.
|
||||
* \param type : The type of the protocol.
|
||||
* \return The protocol that matches the given type.
|
||||
*/
|
||||
Protocol* ProtocolManager::getProtocol(ProtocolType type)
|
||||
{
|
||||
// FIXME: Does m_protocols need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].protocol->getProtocolType() == type)
|
||||
return m_protocols.getData()[i].protocol;
|
||||
if (m_protocols.getData()[i].m_protocol->getProtocolType() == type)
|
||||
return m_protocols.getData()[i].m_protocol;
|
||||
}
|
||||
return NULL;
|
||||
} // getProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Know whether the app is a server.
|
||||
* \return True if this application is in server mode, false elseway.
|
||||
*/
|
||||
bool ProtocolManager::isServer()
|
||||
{
|
||||
return NetworkManager::getInstance()->isServer();
|
||||
} // isServer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/*! \brief Tells if we need to stop the update thread.
|
||||
*/
|
||||
int ProtocolManager::exit()
|
||||
{
|
||||
switch(pthread_mutex_trylock(&m_exit_mutex)) {
|
||||
@ -568,7 +660,7 @@ int ProtocolManager::exit()
|
||||
void ProtocolManager::assignProtocolId(ProtocolInfo* protocol_info)
|
||||
{
|
||||
pthread_mutex_lock(&m_id_mutex);
|
||||
protocol_info->id = m_next_protocol_id;
|
||||
protocol_info->m_id = m_next_protocol_id;
|
||||
m_next_protocol_id++;
|
||||
pthread_mutex_unlock(&m_id_mutex);
|
||||
} // assignProtocolId
|
||||
|
@ -23,7 +23,6 @@
|
||||
#ifndef PROTOCOL_MANAGER_HPP
|
||||
#define PROTOCOL_MANAGER_HPP
|
||||
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/protocol.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
@ -33,77 +32,84 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Event;
|
||||
class STKPeer;
|
||||
|
||||
#define TIME_TO_KEEP_EVENTS 1.0
|
||||
|
||||
/*!
|
||||
* \enum PROTOCOL_STATE
|
||||
* \brief Defines the three states that a protocol can have.
|
||||
/** \enum PROTOCOL_STATE
|
||||
* \brief Defines the three states that a protocol can have.
|
||||
*/
|
||||
enum PROTOCOL_STATE
|
||||
enum ProtocolState
|
||||
{
|
||||
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.
|
||||
};
|
||||
PROTOCOL_STATE_INITIALISING, //!< The protocol is waiting to be started
|
||||
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.
|
||||
}; // ProtocolState
|
||||
|
||||
/*!
|
||||
* \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 ProtocolRequestType
|
||||
* \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
|
||||
enum ProtocolRequestType
|
||||
{
|
||||
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
|
||||
};
|
||||
}; // ProtocolRequestType
|
||||
|
||||
/*!
|
||||
* \struct ProtocolInfo
|
||||
* \brief Stores the information needed to manage protocols
|
||||
*/
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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
|
||||
ProtocolState m_state; //!< The state of the protocol
|
||||
Protocol* m_protocol; //!< A pointer to the protocol
|
||||
uint32_t m_id; //!< The unique id of the protocol
|
||||
} ProtocolInfo;
|
||||
|
||||
/*!
|
||||
* \struct ProtocolRequest
|
||||
* \brief Represents a request to do an action about a protocol.
|
||||
*/
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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
|
||||
/** The type of request. */
|
||||
ProtocolRequestType m_type;
|
||||
|
||||
/** The concerned protocol information. */
|
||||
ProtocolInfo m_protocol_info;
|
||||
} ProtocolRequest;
|
||||
|
||||
/*! \struct ProtocolRequest
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \struct ProtocolRequest
|
||||
* \brief Used to pass the event to protocols that need it
|
||||
*/
|
||||
typedef struct EventProcessingInfo
|
||||
{
|
||||
Event* event;
|
||||
double arrival_time;
|
||||
std::vector<unsigned int> protocols_ids;
|
||||
Event* m_event;
|
||||
double m_arrival_time;
|
||||
std::vector<unsigned int> m_protocols_ids;
|
||||
} EventProcessingInfo;
|
||||
|
||||
/*!
|
||||
* \class ProtocolManager
|
||||
* \brief Manages the protocols at runtime.
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \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.
|
||||
*/
|
||||
* 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 AbstractSingleton<ProtocolManager>,
|
||||
public NoCopy
|
||||
{
|
||||
@ -111,126 +117,31 @@ class ProtocolManager : public AbstractSingleton<ProtocolManager>,
|
||||
static void* mainLoop(void *data);
|
||||
public:
|
||||
|
||||
/*! \brief Stops the protocol manager. */
|
||||
virtual void abort();
|
||||
/*!
|
||||
* \brief Function that processes incoming events.
|
||||
* This function is called by the network manager each time there is an
|
||||
* incoming packet.
|
||||
*/
|
||||
virtual void notifyEvent(Event* event);
|
||||
/*!
|
||||
* \brief WILL BE COMMENTED LATER
|
||||
*/
|
||||
virtual void sendMessage(Protocol* sender, const NetworkString& message, bool reliable = true);
|
||||
/*!
|
||||
* \brief WILL BE COMMENTED LATER
|
||||
*/
|
||||
virtual void sendMessage(Protocol* sender, STKPeer* peer, const NetworkString& message, bool reliable = true);
|
||||
/*!
|
||||
* \brief WILL BE COMMENTED LATER
|
||||
*/
|
||||
virtual void sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message, bool reliable = true);
|
||||
|
||||
/*!
|
||||
* \brief Asks the manager to start a protocol.
|
||||
* This function will store the request, and process it at a time it is
|
||||
* thread-safe.
|
||||
* \param protocol : A pointer to the protocol to start
|
||||
* \return The unique id of the protocol that is being started.
|
||||
*/
|
||||
virtual uint32_t requestStart(Protocol* protocol);
|
||||
/*!
|
||||
* \brief Asks the manager to stop a protocol.
|
||||
* This function will store the request, and process it at a time it is
|
||||
* thread-safe.
|
||||
* \param protocol : A pointer to the protocol to stop
|
||||
*/
|
||||
virtual void requestStop(Protocol* protocol);
|
||||
/*!
|
||||
* \brief Asks the manager to pause a protocol.
|
||||
* This function will store the request, and process it at a time it is
|
||||
* thread-safe.
|
||||
* \param protocol : A pointer to the protocol to pause
|
||||
*/
|
||||
virtual void requestPause(Protocol* protocol);
|
||||
/*!
|
||||
* \brief Asks the manager to unpause a protocol.
|
||||
* This function will store the request, and process it at a time it is
|
||||
* thread-safe.
|
||||
* \param protocol : A pointer to the protocol to unpause
|
||||
*/
|
||||
virtual void requestUnpause(Protocol* protocol);
|
||||
/*!
|
||||
* \brief Notifies the manager that a protocol is terminated.
|
||||
* This function will store the request, and process it at a time it is
|
||||
* thread-safe.
|
||||
* \param protocol : A pointer to the protocol that is finished
|
||||
*/
|
||||
virtual void requestTerminate(Protocol* protocol);
|
||||
|
||||
/*!
|
||||
* \brief Updates the manager.
|
||||
*
|
||||
* This function processes the events queue, notifies the concerned
|
||||
* protocols that they have events to process. Then ask all protocols
|
||||
* to update themselves. Finally processes stored requests about
|
||||
* starting, stoping, pausing etc... protocols.
|
||||
* This function is called by the main loop.
|
||||
* This function IS FPS-dependant.
|
||||
*/
|
||||
virtual void update();
|
||||
/*!
|
||||
* \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 in a thread.
|
||||
* This function IS NOT FPS-dependant.
|
||||
*/
|
||||
virtual void asynchronousUpdate();
|
||||
|
||||
/*!
|
||||
* \brief Get the state of a protocol using its id.
|
||||
* \param id : The id of the protocol you seek the state.
|
||||
* \return The state of the protocol.
|
||||
*/
|
||||
virtual PROTOCOL_STATE getProtocolState(uint32_t id);
|
||||
/*!
|
||||
* \brief Get the state of a protocol using a pointer on it.
|
||||
* \param protocol : A pointer to the protocol you seek the state.
|
||||
* \return The state of the protocol.
|
||||
*/
|
||||
virtual PROTOCOL_STATE getProtocolState(Protocol* protocol);
|
||||
/*!
|
||||
* \brief Get the id of a protocol.
|
||||
* \param protocol : A pointer to the protocol you seek the id.
|
||||
* \return The id of the protocol pointed by the protocol parameter.
|
||||
*/
|
||||
virtual uint32_t getProtocolID(Protocol* protocol);
|
||||
|
||||
/*!
|
||||
* \brief Get a protocol using its id.
|
||||
* \param id : Unique ID of the seek protocol.
|
||||
* \return The protocol that has the ID id.
|
||||
*/
|
||||
virtual Protocol* getProtocol(uint32_t id);
|
||||
/*!
|
||||
* \brief Get a protocol using its type.
|
||||
* \param type : The type of the protocol.
|
||||
* \return The protocol that matches the given type.
|
||||
*/
|
||||
virtual Protocol* getProtocol(PROTOCOL_TYPE type);
|
||||
|
||||
/*! \brief Know whether the app is a server.
|
||||
* \return True if this application is in server mode, false elseway.
|
||||
*/
|
||||
bool isServer();
|
||||
|
||||
/*! \brief Tells if we need to stop the update thread. */
|
||||
int exit();
|
||||
virtual void abort();
|
||||
virtual void propagateEvent(Event* event);
|
||||
virtual void sendMessage(Protocol* sender,
|
||||
const NetworkString& message,
|
||||
bool reliable = true);
|
||||
virtual void sendMessage(Protocol* sender, STKPeer* peer,
|
||||
const NetworkString& message,
|
||||
bool reliable = true);
|
||||
virtual void sendMessageExcept(Protocol* sender, STKPeer* peer,
|
||||
const NetworkString& message,
|
||||
bool reliable = true);
|
||||
virtual uint32_t requestStart(Protocol* protocol);
|
||||
virtual void requestStop(Protocol* protocol);
|
||||
virtual void requestPause(Protocol* protocol);
|
||||
virtual void requestUnpause(Protocol* protocol);
|
||||
virtual void requestTerminate(Protocol* protocol);
|
||||
virtual void update();
|
||||
virtual void asynchronousUpdate();
|
||||
virtual ProtocolState getProtocolState(uint32_t id);
|
||||
virtual ProtocolState getProtocolState(Protocol* protocol);
|
||||
virtual uint32_t getProtocolID(Protocol* protocol);
|
||||
virtual Protocol* getProtocol(uint32_t id);
|
||||
virtual Protocol* getProtocol(ProtocolType type);
|
||||
bool isServer();
|
||||
int exit();
|
||||
|
||||
protected:
|
||||
// protected functions
|
||||
@ -251,12 +162,7 @@ class ProtocolManager : public AbstractSingleton<ProtocolManager>,
|
||||
*/
|
||||
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);
|
||||
virtual void startProtocol(ProtocolInfo &protocol);
|
||||
/*!
|
||||
* \brief Stops a protocol.
|
||||
* Coes nothing. Noone can stop running protocols for now.
|
||||
@ -282,7 +188,7 @@ class ProtocolManager : public AbstractSingleton<ProtocolManager>,
|
||||
*/
|
||||
virtual void protocolTerminated(ProtocolInfo protocol);
|
||||
|
||||
bool propagateEvent(EventProcessingInfo* event, bool synchronous);
|
||||
bool sendEvent(EventProcessingInfo* event, bool synchronous);
|
||||
|
||||
// protected members
|
||||
/** Contains the running protocols.
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "config/player_manager.hpp"
|
||||
#include "modes/world_with_rank.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/network_world.hpp"
|
||||
#include "network/protocols/start_game_protocol.hpp"
|
||||
@ -135,7 +136,7 @@ bool ClientLobbyRoomProtocol::notifyEvent(Event* event)
|
||||
assert(m_setup); // assert that the setup exists
|
||||
if (event->getType() == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
assert(data.size()); // assert that data isn't empty
|
||||
uint8_t message_type = data[0];
|
||||
if (message_type != 0x03 &&
|
||||
@ -161,7 +162,7 @@ bool ClientLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
|
||||
assert(m_setup); // assert that the setup exists
|
||||
if (event->getType() == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
assert(data.size()); // assert that data isn't empty
|
||||
uint8_t message_type = data[0];
|
||||
if (message_type == 0x03 ||
|
||||
@ -285,7 +286,7 @@ void ClientLobbyRoomProtocol::update()
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() != 7 || data[0] != 4 || data[5] != 1) // 7 bytes remains now
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a new player wasn't formated as expected.");
|
||||
@ -328,7 +329,7 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() != 2 || data[0] != 1)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a new player wasn't formated as expected.");
|
||||
@ -359,7 +360,7 @@ void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
NetworkString &data = event->data();
|
||||
if (data.size() < 12 || data[0] != 1 || data[2] != 4 || data[7] != 4) // 12 bytes remains now
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying an accepted connection wasn't formated as expected.");
|
||||
@ -428,7 +429,7 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::connectionRefused(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() != 2 || data[0] != 1) // 2 bytes remains now
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected.");
|
||||
@ -463,7 +464,7 @@ void ClientLobbyRoomProtocol::connectionRefused(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() != 2 || data[0] != 1)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a refused kart selection wasn't formated as expected.");
|
||||
@ -498,7 +499,7 @@ void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() < 3 || data[0] != 1)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a kart selection update wasn't formated as expected.");
|
||||
@ -534,7 +535,7 @@ void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::startGame(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() < 5 || data[0] != 4)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a kart "
|
||||
@ -567,7 +568,7 @@ void ClientLobbyRoomProtocol::startGame(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::startSelection(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() < 5 || data[0] != 4)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a kart "
|
||||
@ -599,12 +600,12 @@ void ClientLobbyRoomProtocol::startSelection(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::raceFinished(Event* event)
|
||||
{
|
||||
if (event->data().size() < 5)
|
||||
NetworkString &data = event->data();
|
||||
if (data.size() < 5)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "Not enough data provided.");
|
||||
return;
|
||||
}
|
||||
NetworkString data = event->data();
|
||||
if (event->getPeer()->getClientServerToken() != data.gui32(1))
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "Bad token");
|
||||
@ -675,7 +676,7 @@ void ClientLobbyRoomProtocol::raceFinished(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::playerMajorVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (!checkDataSizeAndToken(event, 9))
|
||||
return;
|
||||
if (!isByteCorrect(event, 5, 1))
|
||||
@ -698,7 +699,7 @@ void ClientLobbyRoomProtocol::playerMajorVote(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::playerRaceCountVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (!checkDataSizeAndToken(event, 9))
|
||||
return;
|
||||
if (!isByteCorrect(event, 5, 1))
|
||||
@ -721,7 +722,7 @@ void ClientLobbyRoomProtocol::playerRaceCountVote(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::playerMinorVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (!checkDataSizeAndToken(event, 9))
|
||||
return;
|
||||
if (!isByteCorrect(event, 5, 1))
|
||||
@ -745,7 +746,7 @@ void ClientLobbyRoomProtocol::playerMinorVote(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (!checkDataSizeAndToken(event, 10))
|
||||
return;
|
||||
if (!isByteCorrect(event, 5, 1))
|
||||
@ -771,7 +772,7 @@ void ClientLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (!checkDataSizeAndToken(event, 11))
|
||||
return;
|
||||
if (!isByteCorrect(event, 5, 1))
|
||||
@ -797,7 +798,7 @@ void ClientLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::playerLapsVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (!checkDataSizeAndToken(event, 9))
|
||||
return;
|
||||
if (!isByteCorrect(event, 5, 1))
|
||||
|
@ -2,6 +2,9 @@
|
||||
#define CLIENT_LOBBY_ROOM_PROTOCOL_HPP
|
||||
|
||||
#include "network/protocols/lobby_room_protocol.hpp"
|
||||
#include "network/types.hpp"
|
||||
|
||||
class STKPeer;
|
||||
|
||||
class ClientLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "network/protocols/connect_to_peer.hpp"
|
||||
|
||||
#include "network/client_network_manager.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
#include "network/protocols/get_peer_address.hpp"
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
|
||||
#include "network/client_network_manager.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
#include "network/protocols/get_peer_address.hpp"
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
@ -37,31 +38,36 @@
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ConnectToServer::ConnectToServer() :
|
||||
Protocol(NULL, PROTOCOL_CONNECTION)
|
||||
/** Quick join/
|
||||
*/
|
||||
ConnectToServer::ConnectToServer() : Protocol(NULL, PROTOCOL_CONNECTION)
|
||||
{
|
||||
m_server_id = 0;
|
||||
m_server_id = 0;
|
||||
m_host_id = 0;
|
||||
m_quick_join = true;
|
||||
m_state = NONE;
|
||||
}
|
||||
m_state = NONE;
|
||||
} // ConnectToServer()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ConnectToServer::ConnectToServer(uint32_t server_id, uint32_t host_id) :
|
||||
Protocol(NULL, PROTOCOL_CONNECTION)
|
||||
/** Specify server to connect to.
|
||||
* \param server_id Id of server to connect to.
|
||||
* \param host_id Id of host.
|
||||
*/
|
||||
ConnectToServer::ConnectToServer(uint32_t server_id, uint32_t host_id)
|
||||
: Protocol(NULL, PROTOCOL_CONNECTION)
|
||||
{
|
||||
m_server_id = server_id;
|
||||
m_host_id = host_id;
|
||||
m_server_id = server_id;
|
||||
m_host_id = host_id;
|
||||
m_quick_join = false;
|
||||
m_state = NONE;
|
||||
}
|
||||
m_state = NONE;
|
||||
} // ConnectToServer(server, host)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Destructor.
|
||||
*/
|
||||
ConnectToServer::~ConnectToServer()
|
||||
{
|
||||
}
|
||||
} // ~ConnectToServer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@ -74,20 +80,18 @@ bool ConnectToServer::notifyEventAsynchronous(Event* event)
|
||||
m_state = CONNECTED; // we received a message, we are connected
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // notifyEventAsynchronous
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ConnectToServer::setup()
|
||||
{
|
||||
Log::info("ConnectToServer", "SETUPP");
|
||||
Log::info("ConnectToServer", "SETUP");
|
||||
m_state = NONE;
|
||||
m_server_address.clear();
|
||||
m_current_protocol_id = 0;
|
||||
}
|
||||
} // setup
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ConnectToServer::asynchronousUpdate()
|
||||
{
|
||||
switch(m_state)
|
||||
@ -95,154 +99,89 @@ void ConnectToServer::asynchronousUpdate()
|
||||
case NONE:
|
||||
{
|
||||
Log::info("ConnectToServer", "Protocol starting");
|
||||
m_current_protocol_id = m_listener->requestStart(new GetPublicAddress());
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(new GetPublicAddress());
|
||||
m_state = GETTING_SELF_ADDRESS;
|
||||
break;
|
||||
}
|
||||
case GETTING_SELF_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id)
|
||||
== PROTOCOL_STATE_TERMINATED) // now we know the public addr
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) ==
|
||||
PROTOCOL_STATE_TERMINATED) // now we know the public addr
|
||||
{
|
||||
m_state = SHOWING_SELF_ADDRESS;
|
||||
m_current_protocol_id = m_listener->requestStart(new ShowPublicAddress());
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(new ShowPublicAddress());
|
||||
Log::info("ConnectToServer", "Public address known");
|
||||
/*
|
||||
if (m_quick_join)
|
||||
m_current_protocol_id = m_listener->requestStart(new QuickJoinProtocol(&m_server_address, &m_server_id));
|
||||
else
|
||||
m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_server_id, &m_server_address));*/
|
||||
}
|
||||
break;
|
||||
case SHOWING_SELF_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id)
|
||||
== PROTOCOL_STATE_TERMINATED) // now our public address is in the database
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) ==
|
||||
PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
// now our public address is in the database
|
||||
Log::info("ConnectToServer", "Public address shown");
|
||||
if (m_quick_join)
|
||||
{
|
||||
m_current_protocol_id = m_listener->requestStart(new QuickJoinProtocol(&m_server_address, &m_server_id));
|
||||
m_current_protocol_id = m_listener->requestStart(
|
||||
new QuickJoinProtocol(&m_server_address,
|
||||
&m_server_id) );
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_host_id, &m_server_address));
|
||||
m_current_protocol_id = m_listener->requestStart(
|
||||
new GetPeerAddress(m_host_id,
|
||||
&m_server_address) );
|
||||
m_state = GETTING_SERVER_ADDRESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GETTING_SERVER_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id)
|
||||
== PROTOCOL_STATE_TERMINATED) // we know the server address
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) ==
|
||||
PROTOCOL_STATE_TERMINATED) // we know the server address
|
||||
{
|
||||
Log::info("ConnectToServer", "Server's address known");
|
||||
// we're in the same lan (same public ip address) !!
|
||||
if (m_server_address.getIP() ==
|
||||
NetworkManager::getInstance()->getPublicAddress().getIP())
|
||||
Log::info("ConnectToServer",
|
||||
"Server appears to be in the same LAN.");
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(new RequestConnection(m_server_id));
|
||||
}
|
||||
break;
|
||||
case REQUESTING_CONNECTION:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id)
|
||||
== PROTOCOL_STATE_TERMINATED) // server knows we wanna connect
|
||||
{
|
||||
Log::info("ConnectToServer", "Connection request made");
|
||||
if (m_server_address.getIP() == 0 ||
|
||||
m_server_address.getPort() == 0 )
|
||||
{ // server data not correct, hide address and stop
|
||||
m_state = HIDING_ADDRESS;
|
||||
Log::error("ConnectToServer", "Server address is %s",
|
||||
m_server_address.toString().c_str());
|
||||
m_current_protocol_id = m_listener->requestStart(new HidePublicAddress());
|
||||
return;
|
||||
}
|
||||
// we're in the same lan (same public ip address) !!
|
||||
if (m_server_address.getIP() ==
|
||||
NetworkManager::getInstance()->getPublicAddress().getIP())
|
||||
{
|
||||
// just send a broadcast packet, the client will know our ip address and will connect
|
||||
STKHost* host = NetworkManager::getInstance()->getHost();
|
||||
host->stopListening(); // stop the listening
|
||||
TransportAddress sender;
|
||||
|
||||
TransportAddress broadcast_address;
|
||||
broadcast_address.setIP(-1); // 255.255.255.255
|
||||
broadcast_address.setPort(7321); // 0b10101100000101101101111111111111; // for test
|
||||
char data2[] = "aloha_stk\0";
|
||||
host->sendRawPacket((uint8_t*)(data2), 10, broadcast_address);
|
||||
|
||||
Log::info("ConnectToServer", "Waiting broadcast message.");
|
||||
const uint8_t* received_data = host->receiveRawPacket(&sender); // get the sender
|
||||
|
||||
host->startListening(); // start listening again
|
||||
const char data[] = "aloha_stk\0";
|
||||
if (strcmp(data, (char*)(received_data)) == 0)
|
||||
{
|
||||
Log::info("ConnectToServer", "LAN Server found : %s",
|
||||
sender.toString().c_str());
|
||||
#ifndef WIN32
|
||||
// just check if the ip is ours : if so, then just use localhost (127.0.0.1)
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
struct sockaddr_in *sa;
|
||||
getifaddrs (&ifap); // get the info
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
|
||||
{
|
||||
if (ifa->ifa_addr->sa_family==AF_INET)
|
||||
{
|
||||
sa = (struct sockaddr_in *) ifa->ifa_addr;
|
||||
|
||||
// This interface is ours
|
||||
if (ntohl(sa->sin_addr.s_addr) == sender.getIP())
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifap);
|
||||
#else
|
||||
// Query the list of all IP addresses on the local host
|
||||
// First call to GetIpAddrTable with 0 bytes buffer
|
||||
// will return insufficient buffer error, and size
|
||||
// will contain the number of bytes needed for all
|
||||
// data. Repeat the process of querying the size
|
||||
// using GetIpAddrTable in a while loop since it
|
||||
// can happen that an interface comes online between
|
||||
// the previous call to GetIpAddrTable and the next
|
||||
// call.
|
||||
MIB_IPADDRTABLE *table = NULL;
|
||||
unsigned long size = 0;
|
||||
int error = GetIpAddrTable(table, &size, 0);
|
||||
// Also add a count to limit the while loop - in
|
||||
// case that something strange is going on.
|
||||
int count = 0;
|
||||
while(error==ERROR_INSUFFICIENT_BUFFER && count < 10)
|
||||
{
|
||||
delete[] table; // deleting NULL is legal
|
||||
table = (MIB_IPADDRTABLE*)new char[size];
|
||||
error = GetIpAddrTable(table, &size, 0);
|
||||
count ++;
|
||||
} // while insufficient buffer
|
||||
for(unsigned int i=0; i<table->dwNumEntries; i++)
|
||||
{
|
||||
unsigned int ip = ntohl(table->table[i].dwAddr);
|
||||
if(sender.getIP() == ip) // this interface is ours
|
||||
{
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete[] table;
|
||||
|
||||
#endif
|
||||
m_server_address.copy(sender);
|
||||
m_state = CONNECTING;
|
||||
}
|
||||
Log::info("ConnectToServer",
|
||||
"Server appears to be in the same LAN.");
|
||||
}
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(
|
||||
new RequestConnection(m_server_id));
|
||||
}
|
||||
break;
|
||||
case REQUESTING_CONNECTION:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) ==
|
||||
PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
// Server knows we want to connect
|
||||
Log::info("ConnectToServer", "Connection request made");
|
||||
if (m_server_address.getIP() == 0 ||
|
||||
m_server_address.getPort() == 0 )
|
||||
{
|
||||
// server data not correct, hide address and stop
|
||||
m_state = HIDING_ADDRESS;
|
||||
Log::error("ConnectToServer", "Server address is %s",
|
||||
m_server_address.toString().c_str());
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(new HidePublicAddress());
|
||||
return;
|
||||
}
|
||||
if (m_server_address.getIP() == NetworkManager::getInstance()
|
||||
->getPublicAddress().getIP())
|
||||
{
|
||||
// we're in the same lan (same public ip address) !!
|
||||
handleSameLAN();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_state = CONNECTING;
|
||||
m_current_protocol_id = m_listener->requestStart(new PingProtocol(m_server_address, 2.0));
|
||||
m_current_protocol_id = m_listener->requestStart(
|
||||
new PingProtocol(m_server_address, 2.0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -261,20 +200,27 @@ void ConnectToServer::asynchronousUpdate()
|
||||
case CONNECTED:
|
||||
{
|
||||
Log::info("ConnectToServer", "Connected");
|
||||
m_listener->requestTerminate( m_listener->getProtocol(m_current_protocol_id)); // kill the ping protocol because we're connected
|
||||
m_current_protocol_id = m_listener->requestStart(new HidePublicAddress());
|
||||
// Kill the ping protocol because we're connected
|
||||
m_listener->requestTerminate(
|
||||
m_listener->getProtocol(m_current_protocol_id));
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(new HidePublicAddress());
|
||||
ClientNetworkManager::getInstance()->setConnected(true);
|
||||
m_state = HIDING_ADDRESS;
|
||||
break;
|
||||
}
|
||||
case HIDING_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id)
|
||||
== PROTOCOL_STATE_TERMINATED) // we have hidden our address
|
||||
== PROTOCOL_STATE_TERMINATED) // we have hidden our address
|
||||
{
|
||||
Log::info("ConnectToServer", "Address hidden");
|
||||
m_state = DONE;
|
||||
if (ClientNetworkManager::getInstance()->isConnected()) // lobby room protocol if we're connected only
|
||||
m_listener->requestStart(new ClientLobbyRoomProtocol(m_server_address));
|
||||
// lobby room protocol if we're connected only
|
||||
if (ClientNetworkManager::getInstance()->isConnected())
|
||||
{
|
||||
m_listener->requestStart(
|
||||
new ClientLobbyRoomProtocol(m_server_address));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DONE:
|
||||
@ -287,4 +233,88 @@ void ConnectToServer::asynchronousUpdate()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called when the server is on the same LAN. It uses broadcast to
|
||||
* find and conntect to the server.
|
||||
*/
|
||||
void ConnectToServer::handleSameLAN()
|
||||
{
|
||||
// just send a broadcast packet, the client will know our
|
||||
// ip address and will connect
|
||||
STKHost* host = NetworkManager::getInstance()->getHost();
|
||||
host->stopListening(); // stop the listening
|
||||
|
||||
TransportAddress broadcast_address;
|
||||
broadcast_address.setIP(-1); // 255.255.255.255
|
||||
broadcast_address.setPort(7321);
|
||||
char data2[] = "aloha_stk\0";
|
||||
host->sendRawPacket((uint8_t*)(data2), 10, broadcast_address);
|
||||
|
||||
Log::info("ConnectToServer", "Waiting broadcast message.");
|
||||
|
||||
TransportAddress sender;
|
||||
// get the sender
|
||||
const uint8_t* received_data = host->receiveRawPacket(&sender);
|
||||
|
||||
host->startListening(); // start listening again
|
||||
const char data[] = "aloha_stk\0";
|
||||
if (strcmp(data, (char*)(received_data)) == 0)
|
||||
{
|
||||
Log::info("ConnectToServer", "LAN Server found : %s",
|
||||
sender.toString().c_str());
|
||||
#ifndef WIN32
|
||||
// just check if the ip is ours : if so,
|
||||
// then just use localhost (127.0.0.1)
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
struct sockaddr_in *sa;
|
||||
getifaddrs(&ifap); // get the info
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
|
||||
{
|
||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||
{
|
||||
sa = (struct sockaddr_in *) ifa->ifa_addr;
|
||||
|
||||
// This interface is ours
|
||||
if (ntohl(sa->sin_addr.s_addr) == sender.getIP())
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifap);
|
||||
#else
|
||||
// Query the list of all IP addresses on the local host
|
||||
// First call to GetIpAddrTable with 0 bytes buffer
|
||||
// will return insufficient buffer error, and size
|
||||
// will contain the number of bytes needed for all
|
||||
// data. Repeat the process of querying the size
|
||||
// using GetIpAddrTable in a while loop since it
|
||||
// can happen that an interface comes online between
|
||||
// the previous call to GetIpAddrTable and the next
|
||||
// call.
|
||||
MIB_IPADDRTABLE *table = NULL;
|
||||
unsigned long size = 0;
|
||||
int error = GetIpAddrTable(table, &size, 0);
|
||||
// Also add a count to limit the while loop - in
|
||||
// case that something strange is going on.
|
||||
int count = 0;
|
||||
while (error == ERROR_INSUFFICIENT_BUFFER && count < 10)
|
||||
{
|
||||
delete[] table; // deleting NULL is legal
|
||||
table = (MIB_IPADDRTABLE*)new char[size];
|
||||
error = GetIpAddrTable(table, &size, 0);
|
||||
count++;
|
||||
} // while insufficient buffer
|
||||
for (unsigned int i = 0; i < table->dwNumEntries; i++)
|
||||
{
|
||||
unsigned int ip = ntohl(table->table[i].dwAddr);
|
||||
if (sender.getIP() == ip) // this interface is ours
|
||||
{
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete[] table;
|
||||
|
||||
#endif
|
||||
m_server_address.copy(sender);
|
||||
m_state = CONNECTING;
|
||||
}
|
||||
} // handleSameLAN
|
||||
|
@ -21,41 +21,46 @@
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include "network/types.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
#include <string>
|
||||
|
||||
class ConnectToServer : public Protocol, public CallbackObject
|
||||
{
|
||||
public:
|
||||
ConnectToServer(); //!< Quick join
|
||||
ConnectToServer(uint32_t server_id, uint32_t host_id); //!< Specify server id
|
||||
virtual ~ConnectToServer();
|
||||
private:
|
||||
TransportAddress m_server_address;
|
||||
uint32_t m_server_id;
|
||||
uint32_t m_host_id;
|
||||
uint32_t m_current_protocol_id;
|
||||
bool m_quick_join;
|
||||
|
||||
virtual bool notifyEventAsynchronous(Event* event);
|
||||
virtual void setup();
|
||||
virtual void update() {}
|
||||
virtual void asynchronousUpdate();
|
||||
enum State
|
||||
{
|
||||
NONE,
|
||||
GETTING_SELF_ADDRESS,
|
||||
SHOWING_SELF_ADDRESS,
|
||||
GETTING_SERVER_ADDRESS,
|
||||
REQUESTING_CONNECTION,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
HIDING_ADDRESS,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
/** State for finite state machine. */
|
||||
State m_state;
|
||||
|
||||
protected:
|
||||
TransportAddress m_server_address;
|
||||
uint32_t m_server_id;
|
||||
uint32_t m_host_id;
|
||||
uint32_t m_current_protocol_id;
|
||||
bool m_quick_join;
|
||||
void handleSameLAN();
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
GETTING_SELF_ADDRESS,
|
||||
SHOWING_SELF_ADDRESS,
|
||||
GETTING_SERVER_ADDRESS,
|
||||
REQUESTING_CONNECTION,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
HIDING_ADDRESS,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
public:
|
||||
ConnectToServer();
|
||||
ConnectToServer(uint32_t server_id, uint32_t host_id);
|
||||
virtual ~ConnectToServer();
|
||||
|
||||
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE;
|
||||
virtual void setup() OVERRIDE;
|
||||
virtual void asynchronousUpdate();
|
||||
virtual void update() OVERRIDE {}
|
||||
|
||||
}; // class ConnectToServer
|
||||
|
||||
#endif // CONNECT_TO_SERVER_HPP
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
#include "modes/world.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/network_world.hpp"
|
||||
#include "utils/log.hpp"
|
||||
@ -63,7 +66,7 @@ void ControllerEventsProtocol::setup()
|
||||
|
||||
bool ControllerEventsProtocol::notifyEventAsynchronous(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() < 17)
|
||||
{
|
||||
Log::error("ControllerEventsProtocol", "The data supplied was not complete. Size was %d.", data.size());
|
||||
|
@ -4,7 +4,9 @@
|
||||
#include "network/protocol.hpp"
|
||||
|
||||
#include "input/input.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
|
||||
class Controller;
|
||||
class STKPeer;
|
||||
|
||||
class ControllerEventsProtocol : public Protocol
|
||||
{
|
||||
|
@ -6,7 +6,10 @@
|
||||
#include "items/item_manager.hpp"
|
||||
#include "items/powerup.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
GameEventsProtocol::GameEventsProtocol() : Protocol(NULL, PROTOCOL_GAME_EVENTS)
|
||||
@ -21,7 +24,7 @@ bool GameEventsProtocol::notifyEvent(Event* event)
|
||||
{
|
||||
if (event->getType() != EVENT_TYPE_MESSAGE)
|
||||
return true;
|
||||
NetworkString data = event->data();
|
||||
NetworkString &data = event->data();
|
||||
if (data.size() < 5) // for token and type
|
||||
{
|
||||
Log::warn("GameEventsProtocol", "Too short message.");
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
class STKHost;
|
||||
|
||||
class GetPublicAddress : public Protocol
|
||||
{
|
||||
public:
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_world.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
KartUpdateProtocol::KartUpdateProtocol()
|
||||
@ -33,7 +34,7 @@ bool KartUpdateProtocol::notifyEventAsynchronous(Event* event)
|
||||
{
|
||||
if (event->getType() != EVENT_TYPE_MESSAGE)
|
||||
return true;
|
||||
NetworkString ns = event->data();
|
||||
NetworkString &ns = event->data();
|
||||
if (ns.size() < 36)
|
||||
{
|
||||
Log::info("KartUpdateProtocol", "Message too short.");
|
||||
|
@ -4,7 +4,9 @@
|
||||
#include "network/protocol.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
|
||||
#include <list>
|
||||
#include "pthread.h"
|
||||
|
||||
class AbstractKart;
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_world.hpp"
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
@ -65,7 +66,7 @@ bool ServerLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
|
||||
assert(m_setup); // assert that the setup exists
|
||||
if (event->getType() == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
assert(data.size()); // message not empty
|
||||
uint8_t message_type;
|
||||
message_type = data[0];
|
||||
@ -335,7 +336,7 @@ void ServerLobbyRoomProtocol::kartDisconnected(Event* event)
|
||||
void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
{
|
||||
STKPeer* peer = event->getPeer();
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() != 5 || data[0] != 4)
|
||||
{
|
||||
Log::warn("ServerLobbyRoomProtocol", "Receiving badly formated message. Size is %d and first byte %d", data.size(), data[0]);
|
||||
@ -414,7 +415,7 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
STKPeer* peer = event->getPeer();
|
||||
if (!checkDataSizeAndToken(event, 6))
|
||||
return;
|
||||
@ -475,7 +476,7 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::playerMajorVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
NetworkString &data = event->data();
|
||||
STKPeer* peer = event->getPeer();
|
||||
if (!checkDataSizeAndToken(event, 7))
|
||||
return;
|
||||
@ -506,7 +507,7 @@ void ServerLobbyRoomProtocol::playerMajorVote(Event* event)
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::playerRaceCountVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
NetworkString &data = event->data();
|
||||
STKPeer* peer = event->getPeer();
|
||||
if (!checkDataSizeAndToken(event, 7))
|
||||
return;
|
||||
@ -537,7 +538,7 @@ void ServerLobbyRoomProtocol::playerRaceCountVote(Event* event)
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
NetworkString &data = event->data();
|
||||
STKPeer* peer = event->getPeer();
|
||||
if (!checkDataSizeAndToken(event, 7))
|
||||
return;
|
||||
@ -568,7 +569,7 @@ void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
NetworkString &data = event->data();
|
||||
STKPeer* peer = event->getPeer();
|
||||
if (!checkDataSizeAndToken(event, 8))
|
||||
return;
|
||||
@ -601,7 +602,7 @@ void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
NetworkString &data = event->data();
|
||||
STKPeer* peer = event->getPeer();
|
||||
if (!checkDataSizeAndToken(event, 9))
|
||||
return;
|
||||
@ -634,7 +635,7 @@ void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::playerLapsVote(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
NetworkString &data = event->data();
|
||||
STKPeer* peer = event->getPeer();
|
||||
if (!checkDataSizeAndToken(event, 9))
|
||||
return;
|
||||
|
@ -34,7 +34,6 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
void playerLapsVote(Event* event);
|
||||
|
||||
uint8_t m_next_id; //!< Next id to assign to a peer.
|
||||
std::vector<TransportAddress> m_peers;
|
||||
std::vector<uint32_t> m_incoming_peers_ids;
|
||||
uint32_t m_current_protocol_id;
|
||||
bool m_selection_enabled;
|
||||
|
@ -6,10 +6,11 @@
|
||||
#include "input/input_manager.hpp"
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/network_world.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/protocols/synchronization_protocol.hpp"
|
||||
#include "online/online_profile.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
@ -36,7 +37,7 @@ StartGameProtocol::~StartGameProtocol()
|
||||
|
||||
bool StartGameProtocol::notifyEventAsynchronous(Event* event)
|
||||
{
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() < 5)
|
||||
{
|
||||
Log::error("StartGameProtocol", "Too short message.");
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "network/protocols/synchronization_protocol.hpp"
|
||||
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocols/kart_update_protocol.hpp"
|
||||
#include "network/protocols/controller_events_protocol.hpp"
|
||||
@ -35,7 +36,7 @@ bool SynchronizationProtocol::notifyEventAsynchronous(Event* event)
|
||||
{
|
||||
if (event->getType() != EVENT_TYPE_MESSAGE)
|
||||
return true;
|
||||
NetworkString data = event->data();
|
||||
const NetworkString &data = event->data();
|
||||
if (data.size() < 10)
|
||||
{
|
||||
Log::warn("SynchronizationProtocol", "Received a message too short.");
|
||||
|
@ -111,7 +111,7 @@ void ServerNetworkManager::run()
|
||||
Log::info("ServerNetworkManager", "Host initialized.");
|
||||
|
||||
// listen keyboard console input
|
||||
m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t)));
|
||||
m_thread_keyboard = new pthread_t;
|
||||
pthread_create(m_thread_keyboard, NULL, waitInput2, NULL);
|
||||
|
||||
NetworkManager::run();
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/time.hpp"
|
||||
@ -178,12 +179,19 @@ void* STKHost::mainLoop(void* self)
|
||||
{
|
||||
while (enet_host_service(host, &event, 20) != 0)
|
||||
{
|
||||
if (event.type == ENET_EVENT_TYPE_NONE)
|
||||
continue;
|
||||
|
||||
// Create an STKEvent with the event data
|
||||
Event* stk_event = new Event(&event);
|
||||
if (stk_event->getType() == EVENT_TYPE_MESSAGE)
|
||||
logPacket(stk_event->data(), true);
|
||||
if (event.type != ENET_EVENT_TYPE_NONE)
|
||||
NetworkManager::getInstance()->notifyEvent(stk_event);
|
||||
delete stk_event;
|
||||
|
||||
// The event is forwarded to the NetworkManger and from there
|
||||
// there to the ProtocolManager. The ProtocolManager is
|
||||
// responsible for freeing the memory.
|
||||
NetworkManager::getInstance()->propagateEvent(stk_event);
|
||||
|
||||
} // while enet_host_service
|
||||
} // while !mustStopListening
|
||||
|
||||
@ -372,7 +380,7 @@ uint8_t* STKHost::receiveRawPacket(const TransportAddress& sender,
|
||||
}
|
||||
if (addr.sin_family == AF_INET)
|
||||
{
|
||||
TransportAddress a(addr.sin_addr.s_addr);
|
||||
TransportAddress a(ntohl(addr.sin_addr.s_addr));
|
||||
Log::info("STKHost", "IPv4 Address of the sender was %s",
|
||||
a.toString(false).c_str());
|
||||
}
|
||||
|
@ -18,54 +18,42 @@
|
||||
|
||||
#include "network/stk_peer.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/** Constructor for an empty peer.
|
||||
*/
|
||||
STKPeer::STKPeer()
|
||||
{
|
||||
m_peer = NULL;
|
||||
m_player_profile = new NetworkPlayerProfile*;
|
||||
*m_player_profile = NULL;
|
||||
m_client_server_token = new uint32_t;
|
||||
*m_client_server_token = 0;
|
||||
m_token_set = new bool;
|
||||
*m_token_set = false;
|
||||
}
|
||||
m_enet_peer = NULL;
|
||||
m_player_profile = NULL;
|
||||
m_client_server_token = 0;
|
||||
m_token_set = false;
|
||||
} // STKPeer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
STKPeer::STKPeer(const STKPeer& peer)
|
||||
{
|
||||
m_peer = peer.m_peer;
|
||||
m_player_profile = peer.m_player_profile;
|
||||
m_client_server_token = peer.m_client_server_token;
|
||||
m_token_set = peer.m_token_set;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Destructor.
|
||||
*/
|
||||
STKPeer::~STKPeer()
|
||||
{
|
||||
if (m_peer)
|
||||
m_peer = NULL;
|
||||
if (m_enet_peer)
|
||||
m_enet_peer = NULL;
|
||||
if (m_player_profile)
|
||||
delete m_player_profile;
|
||||
m_player_profile = NULL;
|
||||
if (m_client_server_token)
|
||||
delete m_client_server_token;
|
||||
m_client_server_token = NULL;
|
||||
if (m_token_set)
|
||||
delete m_token_set;
|
||||
m_token_set = NULL;
|
||||
}
|
||||
m_client_server_token = 0;
|
||||
} // ~STKPeer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Connect to the specified host.
|
||||
*/
|
||||
bool STKPeer::connectToHost(STKHost* localhost, const TransportAddress &host,
|
||||
uint32_t channel_count, uint32_t data)
|
||||
uint32_t channel_count, uint32_t data)
|
||||
{
|
||||
const ENetAddress address = host.toEnetAddress();
|
||||
const ENetAddress address = host.toEnetAddress();
|
||||
|
||||
ENetPeer* peer = enet_host_connect(localhost->m_host, &address, 2, 0);
|
||||
if (peer == NULL)
|
||||
@ -76,70 +64,70 @@ bool STKPeer::connectToHost(STKHost* localhost, const TransportAddress &host,
|
||||
TransportAddress a(peer->address);
|
||||
Log::verbose("STKPeer", "Connecting to %s", a.toString().c_str());
|
||||
return true;
|
||||
}
|
||||
} // connectToHost
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Disconnect from the server.
|
||||
*/
|
||||
void STKPeer::disconnect()
|
||||
{
|
||||
enet_peer_disconnect(m_peer, 0);
|
||||
}
|
||||
enet_peer_disconnect(m_enet_peer, 0);
|
||||
} // disconnect
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Sends a packet to this host.
|
||||
* \param data The data to send.
|
||||
* \param reliable If the data is sent reliable or not.
|
||||
*/
|
||||
void STKPeer::sendPacket(NetworkString const& data, bool reliable)
|
||||
{
|
||||
TransportAddress a(m_peer->address);
|
||||
TransportAddress a(m_enet_peer->address);
|
||||
Log::verbose("STKPeer", "sending packet of size %d to %s",
|
||||
a.toString().c_str());
|
||||
|
||||
ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1,
|
||||
(reliable ? ENET_PACKET_FLAG_RELIABLE : ENET_PACKET_FLAG_UNSEQUENCED));
|
||||
/* to debug the packet output
|
||||
printf("STKPeer: ");
|
||||
for (unsigned int i = 0; i < data.size(); i++)
|
||||
{
|
||||
printf("%d ", (uint8_t)(data[i]));
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
enet_peer_send(m_peer, 0, packet);
|
||||
}
|
||||
(reliable ? ENET_PACKET_FLAG_RELIABLE
|
||||
: ENET_PACKET_FLAG_UNSEQUENCED));
|
||||
enet_peer_send(m_enet_peer, 0, packet);
|
||||
} // sendPacket
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Returns the IP address (in host format) of this client.
|
||||
*/
|
||||
uint32_t STKPeer::getAddress() const
|
||||
{
|
||||
return ntohl(m_peer->address.host);
|
||||
}
|
||||
return ntohl(m_enet_peer->address.host);
|
||||
} // getAddress
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Returns the port of this peer.
|
||||
*/
|
||||
uint16_t STKPeer::getPort() const
|
||||
{
|
||||
return m_peer->address.port;
|
||||
return m_enet_peer->address.port;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Returns if the peer is connected or not.
|
||||
*/
|
||||
bool STKPeer::isConnected() const
|
||||
{
|
||||
Log::info("STKPeer", "The peer state is %i", m_peer->state);
|
||||
return (m_peer->state == ENET_PEER_STATE_CONNECTED);
|
||||
}
|
||||
Log::info("STKPeer", "The peer state is %i", m_enet_peer->state);
|
||||
return (m_enet_peer->state == ENET_PEER_STATE_CONNECTED);
|
||||
} // isConnected
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool STKPeer::exists() const
|
||||
{
|
||||
return (m_peer != NULL); // assert that the peer exists
|
||||
return (m_enet_peer != NULL); // assert that the peer exists
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool STKPeer::isSamePeer(const STKPeer* peer) const
|
||||
{
|
||||
return peer->m_peer==m_peer;
|
||||
return peer->m_enet_peer==m_enet_peer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -23,48 +23,75 @@
|
||||
#ifndef STK_PEER_HPP
|
||||
#define STK_PEER_HPP
|
||||
|
||||
#include "network/stk_host.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
#include <enet/enet.h>
|
||||
|
||||
class NetworkPlayerProfile;
|
||||
class NetworkString;
|
||||
class STKHost;
|
||||
class TransportAddress;
|
||||
|
||||
/*! \class STKPeer
|
||||
* \brief Represents a peer.
|
||||
* This class is used to interface the ENetPeer structure.
|
||||
*/
|
||||
class STKPeer
|
||||
class STKPeer : public NoCopy
|
||||
{
|
||||
friend class Event;
|
||||
protected:
|
||||
ENetPeer* m_peer;
|
||||
NetworkPlayerProfile** m_player_profile;
|
||||
uint32_t *m_client_server_token;
|
||||
bool *m_token_set;
|
||||
/** Pointer to the corresponding ENet peer data structure. */
|
||||
ENetPeer* m_enet_peer;
|
||||
|
||||
NetworkPlayerProfile* m_player_profile;
|
||||
|
||||
/** The token of this client. */
|
||||
uint32_t m_client_server_token;
|
||||
|
||||
/** True if the token for this peer has been set. */
|
||||
bool m_token_set;
|
||||
|
||||
public:
|
||||
STKPeer();
|
||||
STKPeer(const STKPeer& peer);
|
||||
virtual ~STKPeer();
|
||||
STKPeer();
|
||||
virtual ~STKPeer();
|
||||
|
||||
virtual void sendPacket(const NetworkString& data, bool reliable = true);
|
||||
static bool connectToHost(STKHost* localhost, const TransportAddress& host,
|
||||
uint32_t channel_count, uint32_t data);
|
||||
void disconnect();
|
||||
virtual void sendPacket(const NetworkString& data, bool reliable = true);
|
||||
static bool connectToHost(STKHost* localhost, const TransportAddress& host,
|
||||
uint32_t channel_count, uint32_t data);
|
||||
void disconnect();
|
||||
bool isConnected() const;
|
||||
bool exists() const;
|
||||
uint32_t getAddress() const;
|
||||
uint16_t getPort() const;
|
||||
bool isSamePeer(const STKPeer* peer) const;
|
||||
|
||||
void setClientServerToken(const uint32_t& token) { *m_client_server_token = token; *m_token_set = true; }
|
||||
void unsetClientServerToken() { *m_token_set = false; }
|
||||
void setPlayerProfile(NetworkPlayerProfile* profile) { *m_player_profile = profile; }
|
||||
void setPlayerProfilePtr(NetworkPlayerProfile** profile) { m_player_profile = profile; }
|
||||
|
||||
bool isConnected() const;
|
||||
bool exists() const;
|
||||
uint32_t getAddress() const;
|
||||
uint16_t getPort() const;
|
||||
NetworkPlayerProfile* getPlayerProfile() { return (m_player_profile)?(*m_player_profile):NULL; }
|
||||
uint32_t getClientServerToken() const { return *m_client_server_token; }
|
||||
bool isClientServerTokenSet() const { return *m_token_set; }
|
||||
|
||||
bool isSamePeer(const STKPeer* peer) const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the token for this client. */
|
||||
void setClientServerToken(const uint32_t& token)
|
||||
{
|
||||
m_client_server_token = token;
|
||||
m_token_set = true;
|
||||
} // setClientServerToken
|
||||
// ------------------------------------------------------------------------
|
||||
void unsetClientServerToken() { m_token_set = false; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setPlayerProfile(NetworkPlayerProfile* profile)
|
||||
{
|
||||
m_player_profile = profile;
|
||||
} // setPlayerProfile
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the player profile of this peer. */
|
||||
NetworkPlayerProfile* getPlayerProfile()
|
||||
{
|
||||
return m_player_profile;
|
||||
} // getPlayerProfile
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the token of this client. */
|
||||
uint32_t getClientServerToken() const { return m_client_server_token; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if the token for this client is known. */
|
||||
bool isClientServerTokenSet() const { return m_token_set; }
|
||||
|
||||
}; // STKPeer
|
||||
|
||||
|
@ -305,6 +305,7 @@ void RaceManager::startNew(bool from_overworld)
|
||||
->getActivePlayerProfile(0)
|
||||
->getUniqueID(),
|
||||
m_grand_prix.getId(),
|
||||
m_minor_mode,
|
||||
m_player_karts.size());
|
||||
|
||||
// Saved GP only in offline mode
|
||||
@ -398,6 +399,7 @@ void RaceManager::startNew(bool from_overworld)
|
||||
->getActivePlayerProfile(0)
|
||||
->getUniqueID(),
|
||||
m_grand_prix.getId(),
|
||||
m_minor_mode,
|
||||
m_player_karts.size());
|
||||
}
|
||||
}
|
||||
@ -551,6 +553,7 @@ void RaceManager::saveGP()
|
||||
m_saved_gp = new SavedGrandPrix(
|
||||
StateManager::get()->getActivePlayerProfile(0)->getUniqueID(),
|
||||
m_grand_prix.getId(),
|
||||
m_minor_mode,
|
||||
m_difficulty,
|
||||
(int)m_player_karts.size(),
|
||||
m_track_number,
|
||||
|
@ -205,6 +205,7 @@ void GPInfoDialog::addButtons()
|
||||
->getActivePlayerProfile(0)
|
||||
->getUniqueID(),
|
||||
m_gp.getId(),
|
||||
race_manager->getMinorMode(),
|
||||
race_manager->getNumLocalPlayers());
|
||||
|
||||
okBtn->m_properties[PROP_ID] = "start";
|
||||
|
@ -134,6 +134,7 @@ void GPInfoScreen::beforeAddingWidget()
|
||||
SavedGrandPrix* saved_gp = SavedGrandPrix::getSavedGP(
|
||||
StateManager::get()->getActivePlayerProfile(0)->getUniqueID(),
|
||||
m_gp.getId(),
|
||||
race_manager->getMinorMode(),
|
||||
race_manager->getNumLocalPlayers());
|
||||
|
||||
int tracks = m_gp.getTrackNames().size();
|
||||
|
Loading…
Reference in New Issue
Block a user