improving again the protocol system, fixing some pointer issues that might appear
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13164 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
212b77fef3
commit
3c3868210f
Binary file not shown.
@ -23,6 +23,7 @@
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
#include "network/protocols/get_peer_address.hpp"
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
#include "network/protocols/client_lobby_room_protocol.hpp"
|
||||
|
||||
#include "utils/log.hpp"
|
||||
|
||||
@ -35,7 +36,7 @@ void* waitInput(void* data)
|
||||
std::string str = "";
|
||||
bool stop = false;
|
||||
int n = 0;
|
||||
|
||||
|
||||
while(!stop)
|
||||
{
|
||||
getline(std::cin, str);
|
||||
@ -55,7 +56,15 @@ void* waitInput(void* data)
|
||||
{
|
||||
ProtocolManager::getInstance()->requestStart(new ConnectToServer(n));
|
||||
}
|
||||
else
|
||||
else if (str == "select")
|
||||
{
|
||||
std::string str2;
|
||||
getline(std::cin, str2);
|
||||
Protocol* protocol = ProtocolManager::getInstance()->getProtocol(PROTOCOL_LOBBY_ROOM);
|
||||
ClientLobbyRoomProtocol* clrp = static_cast<ClientLobbyRoomProtocol*>(protocol);
|
||||
clrp->requestKartSelection(str2);
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkString msg;
|
||||
msg.ai8(0);
|
||||
@ -65,7 +74,7 @@ void* waitInput(void* data)
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -79,9 +88,9 @@ ClientNetworkManager::~ClientNetworkManager()
|
||||
{
|
||||
}
|
||||
|
||||
void ClientNetworkManager::run()
|
||||
void ClientNetworkManager::run()
|
||||
{
|
||||
if (enet_initialize() != 0)
|
||||
if (enet_initialize() != 0)
|
||||
{
|
||||
Log::error("ClientNetworkManager", "Could not initialize enet.\n");
|
||||
return;
|
||||
@ -89,11 +98,11 @@ void ClientNetworkManager::run()
|
||||
m_localhost = new STKHost();
|
||||
m_localhost->setupClient(1, 2, 0, 0);
|
||||
m_localhost->startListening();
|
||||
|
||||
|
||||
// listen keyboard console input
|
||||
m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t)));
|
||||
pthread_create(m_thread_keyboard, NULL, waitInput, NULL);
|
||||
|
||||
|
||||
NetworkManager::run();
|
||||
}
|
||||
|
||||
|
@ -47,11 +47,11 @@ Event::Event(ENetEvent* event)
|
||||
else if (event->data)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
m_packet = NULL;
|
||||
if (event->packet)
|
||||
m_packet = event->packet;
|
||||
|
||||
|
||||
if (m_packet)
|
||||
enet_packet_destroy(m_packet); // we got all we need, just remove the data.
|
||||
|
||||
@ -73,7 +73,16 @@ Event::Event(ENetEvent* event)
|
||||
Log::verbose("Event", "Creating a new peer, address are STKPeer:%ld, Peer:%ld", (long int)(new_peer), (long int)(event->peer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Event::Event(const Event& event)
|
||||
{
|
||||
m_packet = NULL;
|
||||
data = event.data;
|
||||
// copy the peer
|
||||
peer = new STKPeer(*event.peer);
|
||||
type = event.type;
|
||||
}
|
||||
|
||||
Event::~Event()
|
||||
{
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ enum EVENT_TYPE
|
||||
/*!
|
||||
* \class Event
|
||||
* \brief Class representing an event that need to pass trough the system.
|
||||
* This is used to remove ENet dependency in the network.
|
||||
* This is used to remove ENet dependency in the network.
|
||||
* It interfaces the ENetEvent structure.
|
||||
* The user has to be extremely careful about the peer.
|
||||
* Indeed, when packets are logged, the state of the peer cannot be stored at
|
||||
@ -51,20 +51,24 @@ class Event
|
||||
* \param event : The event that needs to be translated.
|
||||
*/
|
||||
Event(ENetEvent* event);
|
||||
/*! \brief Constructor
|
||||
* \param event : The event to copy.
|
||||
*/
|
||||
Event(const Event& event);
|
||||
/*! \brief Destructor
|
||||
* frees the memory of the ENetPacket.
|
||||
*/
|
||||
~Event();
|
||||
|
||||
|
||||
/*! \brief Remove bytes at the beginning of data.
|
||||
* \param size : The number of bytes to remove.
|
||||
*/
|
||||
void removeFront(int size);
|
||||
|
||||
|
||||
EVENT_TYPE type; //!< Type of the event.
|
||||
NetworkString data; //!< Copy of the data passed by the event.
|
||||
STKPeer* peer; //!< Pointer to the peer that triggered that event.
|
||||
|
||||
|
||||
private:
|
||||
ENetPacket* m_packet; //!< A pointer on the ENetPacket to be deleted.
|
||||
};
|
||||
|
@ -34,19 +34,20 @@ GameSetup::~GameSetup()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GameSetup::addPlayer(NetworkPlayerProfile profile)
|
||||
void GameSetup::addPlayer(NetworkPlayerProfile* profile)
|
||||
{
|
||||
m_players.push_back(profile);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool GameSetup::removePlayer(uint32_t id)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_players.size(); i++)
|
||||
{
|
||||
if (m_players[i].user_profile->getUserID() == id)
|
||||
if (m_players[i]->user_profile->getUserID() == id)
|
||||
{
|
||||
delete m_players[i];
|
||||
m_players.erase(m_players.begin()+i, m_players.begin()+i+1);
|
||||
Log::verbose("GameSetup", "Removed a player from the game setup.");
|
||||
return true;
|
||||
@ -56,12 +57,12 @@ bool GameSetup::removePlayer(uint32_t id)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool GameSetup::removePlayer(uint8_t id)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_players.size(); i++)
|
||||
{
|
||||
if (m_players[i].race_id == id) // check the given id
|
||||
if (m_players[i]->race_id == id) // check the given id
|
||||
{
|
||||
m_players.erase(m_players.begin()+i, m_players.begin()+i+1);
|
||||
Log::verbose("GameSetup", "Removed a player from the game setup.");
|
||||
@ -72,28 +73,42 @@ bool GameSetup::removePlayer(uint8_t id)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void GameSetup::setPlayerKart(uint8_t id, std::string kart_name)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_players.size(); i++)
|
||||
{
|
||||
if (m_players[i]->race_id == id)
|
||||
{
|
||||
m_players[i]->kart_name = kart_name;
|
||||
Log::info("GameSetup", "Player %d took kart %s", id, kart_name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const NetworkPlayerProfile* GameSetup::getProfile(uint32_t id)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_players.size(); i++)
|
||||
{
|
||||
if (m_players[i].user_profile->getUserID() == id)
|
||||
if (m_players[i]->user_profile->getUserID() == id)
|
||||
{
|
||||
return &m_players[i];
|
||||
return m_players[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
const NetworkPlayerProfile* GameSetup::getProfile(uint8_t id)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_players.size(); i++)
|
||||
{
|
||||
if (m_players[i].race_id == id)
|
||||
if (m_players[i]->race_id == id)
|
||||
{
|
||||
return &m_players[i];
|
||||
return m_players[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -105,7 +120,7 @@ bool GameSetup::isKartAvailable(std::string kart_name)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_players.size(); i++)
|
||||
{
|
||||
if (m_players[i].kart_name == kart_name)
|
||||
if (m_players[i]->kart_name == kart_name)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -28,14 +28,14 @@
|
||||
#include <string>
|
||||
|
||||
/*! \class PlayerProfile
|
||||
* \brief Contains the profile of a player.
|
||||
* \brief Contains the profile of a player.
|
||||
*/
|
||||
class NetworkPlayerProfile
|
||||
class NetworkPlayerProfile
|
||||
{
|
||||
public:
|
||||
NetworkPlayerProfile() { race_id = 0; user_profile = NULL; }
|
||||
~NetworkPlayerProfile() {}
|
||||
|
||||
|
||||
uint8_t race_id; //!< The id of the player for the race
|
||||
std::string kart_name; //!< The selected kart.
|
||||
OnlineUser* user_profile; //!< Pointer to the lobby profile
|
||||
@ -50,19 +50,22 @@ class GameSetup
|
||||
public:
|
||||
GameSetup();
|
||||
virtual ~GameSetup();
|
||||
|
||||
|
||||
void addPlayer(NetworkPlayerProfile profile); //!< Add a player.
|
||||
void addPlayer(NetworkPlayerProfile* profile); //!< Add a player.
|
||||
bool removePlayer(uint32_t id); //!< Remove a player by id.
|
||||
bool removePlayer(uint8_t id); //!< Remove a player by local id.
|
||||
|
||||
void setPlayerKart(uint8_t id, std::string kart_name); //!< Set the kart of a player
|
||||
|
||||
int getPlayerCount() { return m_players.size(); }
|
||||
const NetworkPlayerProfile* getProfile(uint32_t id); //!< Get a profile by database id
|
||||
const NetworkPlayerProfile* getProfile(uint8_t id); //!< Get the profile by the lobby id
|
||||
|
||||
|
||||
bool isKartAvailable(std::string kart_name);
|
||||
|
||||
bool isKartAllowed(std::string kart_name) {return true; }
|
||||
|
||||
protected:
|
||||
std::vector<NetworkPlayerProfile> m_players; //!< Information about players
|
||||
std::vector<NetworkPlayerProfile*> m_players; //!< Information about players
|
||||
NetworkPlayerProfile m_self_profile; //!< Information about self (client only)
|
||||
};
|
||||
|
||||
|
@ -43,12 +43,12 @@ NetworkManager::NetworkManager()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetworkManager::~NetworkManager()
|
||||
NetworkManager::~NetworkManager()
|
||||
{
|
||||
ProtocolManager::kill();
|
||||
|
||||
|
||||
if (m_localhost)
|
||||
delete m_localhost;
|
||||
delete m_localhost;
|
||||
while(!m_peers.empty())
|
||||
{
|
||||
delete m_peers.back();
|
||||
@ -59,7 +59,7 @@ NetworkManager::~NetworkManager()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void NetworkManager::run()
|
||||
{
|
||||
{
|
||||
// create the protocol manager
|
||||
ProtocolManager::getInstance<ProtocolManager>();
|
||||
}
|
||||
@ -70,7 +70,7 @@ bool NetworkManager::connect(TransportAddress peer)
|
||||
{
|
||||
if (peerExists(peer))
|
||||
return isConnectedTo(peer);
|
||||
|
||||
|
||||
return STKPeer::connectToHost(m_localhost, peer, 2, 0);
|
||||
}
|
||||
|
||||
@ -89,54 +89,55 @@ void NetworkManager::setManualSocketsMode(bool manual)
|
||||
void NetworkManager::notifyEvent(Event* event)
|
||||
{
|
||||
Log::info("NetworkManager", "EVENT received of type %d", (int)(event->type));
|
||||
switch (event->type)
|
||||
|
||||
if (event->type == EVENT_TYPE_CONNECTED)
|
||||
{
|
||||
case EVENT_TYPE_CONNECTED:
|
||||
Log::debug("NetworkManager", "A client has just connected. There are now %lu peers.", m_peers.size() + 1);
|
||||
Log::verbose("NetworkManager", "Address of event->peer after connection : %ld", (long int)(event->peer));
|
||||
// create the new peer:
|
||||
m_peers.push_back(event->peer);
|
||||
break;
|
||||
case EVENT_TYPE_DISCONNECTED:
|
||||
{
|
||||
Log::debug("NetworkManager", "Disconnected host: %i.%i.%i.%i:%i", event->peer->getAddress()>>24&0xff, event->peer->getAddress()>>16&0xff, event->peer->getAddress()>>8&0xff, event->peer->getAddress()&0xff,event->peer->getPort());
|
||||
// remove the peer:
|
||||
bool removed = false;
|
||||
for (unsigned int i = 0; i < m_peers.size(); i++)
|
||||
{
|
||||
Log::error("NetworkManager", "Saved : %ld, Sender : %ld", (long int)(m_peers[i]), (long int)(event->peer));
|
||||
if (m_peers[i] == event->peer && !removed) // remove only one
|
||||
{
|
||||
delete m_peers[i];
|
||||
m_peers.erase(m_peers.begin()+i, m_peers.begin()+i+1);
|
||||
Log::verbose("NetworkManager", "The peer has been removed from the Network Manager.");
|
||||
removed = true;
|
||||
}
|
||||
else if (m_peers[i] == event->peer)
|
||||
{
|
||||
Log::fatal("NetworkManager", "Multiple peers match the disconnected one.");
|
||||
}
|
||||
}
|
||||
if (!removed)
|
||||
Log::warn("NetworkManager", "The peer that has been disconnected was not registered by the Network Manager.");
|
||||
|
||||
Log::debug("NetworkManager", "Somebody is now disconnected. There are now %lu peers.", m_peers.size());
|
||||
|
||||
|
||||
} break;
|
||||
case EVENT_TYPE_MESSAGE:
|
||||
{
|
||||
//exit(0);
|
||||
uint32_t addr = event->peer->getAddress();
|
||||
Log::info("NetworkManager", "Message, Sender : %i.%i.%i.%i, message = \"%s\"",
|
||||
((addr>>24)&0xff),
|
||||
((addr>>16)&0xff),
|
||||
((addr>>8)&0xff),
|
||||
(addr&0xff), event->data.c_str());
|
||||
|
||||
} break;
|
||||
Log::debug("NetworkManager", "A client has just connected. There are now %lu peers.", m_peers.size() + 1);
|
||||
Log::verbose("NetworkManager", "Address of event->peer after connection : %ld", (long int)(event->peer));
|
||||
// create the new peer:
|
||||
m_peers.push_back(event->peer);
|
||||
}
|
||||
if (event->type == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
uint32_t addr = event->peer->getAddress();
|
||||
Log::info("NetworkManager", "Message, Sender : %i.%i.%i.%i, message = \"%s\"",
|
||||
((addr>>24)&0xff),
|
||||
((addr>>16)&0xff),
|
||||
((addr>>8)&0xff),
|
||||
(addr&0xff), event->data.c_str());
|
||||
|
||||
}
|
||||
|
||||
// notify for the event now.
|
||||
ProtocolManager::getInstance()->notifyEvent(event);
|
||||
|
||||
if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
{
|
||||
Log::debug("NetworkManager", "Disconnected host: %i.%i.%i.%i:%i", event->peer->getAddress()>>24&0xff, event->peer->getAddress()>>16&0xff, event->peer->getAddress()>>8&0xff, event->peer->getAddress()&0xff,event->peer->getPort());
|
||||
// remove the peer:
|
||||
bool removed = false;
|
||||
for (unsigned int i = 0; i < m_peers.size(); i++)
|
||||
{
|
||||
Log::error("NetworkManager", "Saved : %ld, Sender : %ld", (long int)(m_peers[i]), (long int)(event->peer));
|
||||
if (m_peers[i] == event->peer && !removed) // remove only one
|
||||
{
|
||||
delete m_peers[i];
|
||||
m_peers.erase(m_peers.begin()+i, m_peers.begin()+i+1);
|
||||
Log::verbose("NetworkManager", "The peer has been removed from the Network Manager.");
|
||||
removed = true;
|
||||
}
|
||||
else if (m_peers[i] == event->peer)
|
||||
{
|
||||
Log::fatal("NetworkManager", "Multiple peers match the disconnected one.");
|
||||
}
|
||||
}
|
||||
if (!removed)
|
||||
Log::warn("NetworkManager", "The peer that has been disconnected was not registered by the Network Manager.");
|
||||
|
||||
Log::debug("NetworkManager", "Somebody is now disconnected. There are now %lu peers.", m_peers.size());
|
||||
}
|
||||
|
||||
delete event;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -141,6 +141,7 @@ class NetworkString
|
||||
inline uint8_t getUInt8(int pos = 0) { return get<uint8_t,1>(pos); }
|
||||
inline char getChar(int pos = 0) { return get<char,1>(pos); }
|
||||
inline unsigned char getUChar(int pos = 0) { return get<unsigned char,1>(pos); }
|
||||
std::string getString(int pos = 0) { return std::string(m_string.c_str()+pos); }
|
||||
|
||||
inline int gi(int pos = 0) { return get<int,4>(pos); }
|
||||
inline uint32_t gui(int pos = 0) { return get<uint32_t,4>(pos); }
|
||||
@ -149,6 +150,7 @@ class NetworkString
|
||||
inline uint8_t gui8(int pos = 0) { return get<uint8_t,1>(pos); }
|
||||
inline char gc(int pos = 0) { return get<char,1>(pos); }
|
||||
inline unsigned char guc(int pos = 0) { return get<unsigned char,1>(pos); }
|
||||
std::string gs(int pos = 0) { return std::string(m_string.c_str()+pos); }
|
||||
|
||||
double getDouble(int pos = 0) //!< BEWARE OF PRECISION
|
||||
{
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
|
||||
Protocol::Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type)
|
||||
{
|
||||
m_callback_object = callback_object;
|
||||
@ -43,7 +45,7 @@ void Protocol::kill()
|
||||
|
||||
void Protocol::setListener(ProtocolManager* listener)
|
||||
{
|
||||
m_listener = listener;
|
||||
m_listener = listener;
|
||||
}
|
||||
|
||||
PROTOCOL_TYPE Protocol::getProtocolType()
|
||||
|
@ -19,10 +19,12 @@
|
||||
#ifndef PROTOCOL_HPP
|
||||
#define PROTOCOL_HPP
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/types.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
class ProtocolManager;
|
||||
|
||||
/** \enum PROTOCOL_TYPE
|
||||
* \brief The types that protocols can have. This is used to select which protocol receives which event.
|
||||
* \ingroup network
|
||||
@ -36,7 +38,7 @@ enum PROTOCOL_TYPE
|
||||
};
|
||||
|
||||
/** \class Protocol
|
||||
* \brief Abstract class used to define the global protocol functions.
|
||||
* \brief Abstract class used to define the global protocol functions.
|
||||
* A protocol is an entity that is started at a point, and that is updated by a thread.
|
||||
* A protocol can be terminated by an other class, or it can terminate itself if has fulfilled its role.
|
||||
* This class must be inherited to make any network job.
|
||||
@ -57,44 +59,44 @@ class Protocol
|
||||
/*!
|
||||
* \brief Destructor
|
||||
*/
|
||||
virtual ~Protocol();
|
||||
|
||||
virtual ~Protocol();
|
||||
|
||||
/*!
|
||||
* \brief Notify a protocol matching the Event type of that event.
|
||||
* \param event : Pointer to the event.
|
||||
*/
|
||||
virtual void notifyEvent(Event* event) = 0;
|
||||
|
||||
/*!
|
||||
|
||||
/*!
|
||||
* \brief Set the protocol listener.
|
||||
* \param listener : Pointer to the listener.
|
||||
*/
|
||||
void setListener(ProtocolManager* listener);
|
||||
|
||||
/*!
|
||||
|
||||
/*!
|
||||
* \brief Called when the protocol is going to start. Must be re-defined by subclasses.
|
||||
*/
|
||||
virtual void setup() = 0;
|
||||
/*!
|
||||
* \brief Called when the protocol is paused (by an other entity or by itself).
|
||||
/*!
|
||||
* \brief Called when the protocol is paused (by an other entity or by itself).
|
||||
* This function must be called by the subclasse's pause function if re-defined.
|
||||
*/
|
||||
virtual void pause();
|
||||
/*!
|
||||
* \brief Called when the protocol is unpaused.
|
||||
/*!
|
||||
* \brief Called when the protocol is unpaused.
|
||||
* This function must be called by the subclasse's unpause function if re-defined.
|
||||
*/
|
||||
virtual void unpause();
|
||||
/*!
|
||||
/*!
|
||||
* \brief Called by the protocol listener as often as possible. Must be re-defined.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
/*!
|
||||
/*!
|
||||
* \brief Called when the protocol is to be killed.
|
||||
*/
|
||||
virtual void kill();
|
||||
|
||||
/*!
|
||||
|
||||
/*!
|
||||
* \brief Method to get a protocol's type.
|
||||
* \return The protocol type.
|
||||
*/
|
||||
|
@ -37,7 +37,7 @@ void* protocolManagerUpdate(void* data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ProtocolManager::ProtocolManager()
|
||||
ProtocolManager::ProtocolManager()
|
||||
{
|
||||
pthread_mutex_init(&m_events_mutex, NULL);
|
||||
pthread_mutex_init(&m_protocols_mutex, NULL);
|
||||
@ -45,8 +45,8 @@ ProtocolManager::ProtocolManager()
|
||||
pthread_mutex_init(&m_id_mutex, NULL);
|
||||
pthread_mutex_init(&m_exit_mutex, NULL);
|
||||
m_next_protocol_id = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
pthread_mutex_lock(&m_exit_mutex); // will let the update function run
|
||||
m_update_thread = (pthread_t*)(malloc(sizeof(pthread_t)));
|
||||
pthread_create(m_update_thread, NULL, protocolManagerUpdate, this);
|
||||
@ -70,7 +70,7 @@ ProtocolManager::~ProtocolManager()
|
||||
pthread_mutex_unlock(&m_protocols_mutex);
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
pthread_mutex_unlock(&m_id_mutex);
|
||||
|
||||
|
||||
pthread_mutex_destroy(&m_events_mutex);
|
||||
pthread_mutex_destroy(&m_protocols_mutex);
|
||||
pthread_mutex_destroy(&m_requests_mutex);
|
||||
@ -80,8 +80,9 @@ ProtocolManager::~ProtocolManager()
|
||||
|
||||
void ProtocolManager::notifyEvent(Event* event)
|
||||
{
|
||||
Event* event2 = new Event(*event);
|
||||
pthread_mutex_lock(&m_events_mutex);
|
||||
m_events_to_process.push_back(event); // add the event to the queue
|
||||
m_events_to_process.push_back(event2); // add the event to the queue
|
||||
pthread_mutex_unlock(&m_events_mutex);
|
||||
}
|
||||
|
||||
@ -89,7 +90,7 @@ void ProtocolManager::sendMessage(Protocol* sender, const NetworkString& message
|
||||
{
|
||||
NetworkString newMessage;
|
||||
newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type
|
||||
newMessage += message;
|
||||
newMessage += message;
|
||||
NetworkManager::getInstance()->sendPacket(newMessage);
|
||||
}
|
||||
|
||||
@ -97,14 +98,14 @@ void ProtocolManager::sendMessage(Protocol* sender, STKPeer* peer, const Network
|
||||
{
|
||||
NetworkString newMessage;
|
||||
newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type
|
||||
newMessage += message;
|
||||
newMessage += message;
|
||||
NetworkManager::getInstance()->sendPacket(peer, newMessage);
|
||||
}
|
||||
void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message)
|
||||
{
|
||||
NetworkString newMessage;
|
||||
newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type
|
||||
newMessage += message;
|
||||
newMessage += message;
|
||||
NetworkManager::getInstance()->sendPacketExcept(peer, newMessage);
|
||||
}
|
||||
|
||||
@ -122,7 +123,7 @@ uint32_t ProtocolManager::requestStart(Protocol* protocol)
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
|
||||
|
||||
return info.id;
|
||||
}
|
||||
|
||||
@ -187,7 +188,7 @@ void ProtocolManager::startProtocol(ProtocolInfo protocol)
|
||||
}
|
||||
void ProtocolManager::stopProtocol(ProtocolInfo protocol)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
void ProtocolManager::pauseProtocol(ProtocolInfo protocol)
|
||||
{
|
||||
@ -239,7 +240,7 @@ void ProtocolManager::update()
|
||||
Event* event = m_events_to_process.back();
|
||||
m_events_to_process.pop_back();
|
||||
pthread_mutex_unlock(&m_events_mutex); // release the mutex
|
||||
|
||||
|
||||
PROTOCOL_TYPE searchedProtocol = PROTOCOL_NONE;
|
||||
if (event->type == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
@ -259,9 +260,10 @@ void ProtocolManager::update()
|
||||
{
|
||||
Log::debug("ProtocolManager", "Message is \"%s\"", event->data.c_str());
|
||||
}
|
||||
delete event->peer; // because we made a copy of the peer
|
||||
delete event;
|
||||
}
|
||||
|
||||
|
||||
// now update all protocols
|
||||
pthread_mutex_lock(&m_protocols_mutex);
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
@ -269,8 +271,8 @@ void ProtocolManager::update()
|
||||
if (m_protocols[i].state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols[i].protocol->update();
|
||||
}
|
||||
pthread_mutex_unlock(&m_protocols_mutex);
|
||||
|
||||
pthread_mutex_unlock(&m_protocols_mutex);
|
||||
|
||||
// process queued events for protocols
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
@ -316,7 +318,7 @@ PROTOCOL_STATE ProtocolManager::getProtocolState(uint32_t id)
|
||||
if (m_requests[i].protocol_info.id == id) // the protocol is going to be started
|
||||
return PROTOCOL_STATE_RUNNING; // we can say it's running
|
||||
}
|
||||
return PROTOCOL_STATE_TERMINATED; // else, it's already finished
|
||||
return PROTOCOL_STATE_TERMINATED; // else, it's already finished
|
||||
}
|
||||
|
||||
PROTOCOL_STATE ProtocolManager::getProtocolState(Protocol* protocol)
|
||||
@ -354,6 +356,16 @@ Protocol* ProtocolManager::getProtocol(uint32_t id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Protocol* ProtocolManager::getProtocol(PROTOCOL_TYPE type)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
{
|
||||
if (m_protocols[i].protocol->getProtocolType() == type)
|
||||
return m_protocols[i].protocol;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ProtocolManager::isServer()
|
||||
{
|
||||
return NetworkManager::getInstance()->isServer();
|
||||
|
@ -26,39 +26,38 @@
|
||||
#include "network/singleton.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/protocol.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Protocol;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \enum PROTOCOL_STATE
|
||||
* \brief Defines the three states that a protocol can have.
|
||||
*/
|
||||
enum PROTOCOL_STATE
|
||||
{
|
||||
PROTOCOL_STATE_RUNNING, //!< The protocol is being updated everytime.
|
||||
PROTOCOL_STATE_PAUSED, //!< The protocol is paused.
|
||||
PROTOCOL_STATE_PAUSED, //!< The protocol is paused.
|
||||
PROTOCOL_STATE_TERMINATED //!< The protocol is terminated/does not exist.
|
||||
};
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \enum PROTOCOL_REQUEST_TYPE
|
||||
* \brief Defines actions that can be done about protocols.
|
||||
* This enum is used essentially to keep the manager thread-safe and
|
||||
* This enum is used essentially to keep the manager thread-safe and
|
||||
* to avoid protocols modifying directly their state.
|
||||
*/
|
||||
enum PROTOCOL_REQUEST_TYPE
|
||||
{
|
||||
PROTOCOL_REQUEST_START, //!< Start a protocol
|
||||
PROTOCOL_REQUEST_STOP, //!< Stop a protocol
|
||||
PROTOCOL_REQUEST_STOP, //!< Stop a protocol
|
||||
PROTOCOL_REQUEST_PAUSE, //!< Pause a protocol
|
||||
PROTOCOL_REQUEST_UNPAUSE, //!< Unpause a protocol
|
||||
PROTOCOL_REQUEST_TERMINATE //!< Terminate a protocol
|
||||
};
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \struct ProtocolInfo
|
||||
* \brief Stores the information needed to manage protocols
|
||||
*/
|
||||
@ -68,7 +67,7 @@ typedef struct ProtocolInfo
|
||||
Protocol* protocol; //!< A pointer to the protocol
|
||||
uint32_t id; //!< The unique id of the protocol
|
||||
} ProtocolInfo;
|
||||
|
||||
|
||||
/*!
|
||||
* \struct ProtocolRequest
|
||||
* \brief Represents a request to do an action about a protocol.
|
||||
@ -79,43 +78,43 @@ typedef struct ProtocolRequest
|
||||
ProtocolInfo protocol_info; //!< The concerned protocol information
|
||||
} ProtocolRequest;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \class ProtocolManager
|
||||
* \brief Manages the protocols at runtime.
|
||||
*
|
||||
* This class is in charge of storing and managing protocols.
|
||||
* It is a singleton as there can be only one protocol manager per game
|
||||
* instance. Any game object that wants to start a protocol must create a
|
||||
* protocol and give it to this singleton. The protocols are updated in a
|
||||
*
|
||||
* 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
|
||||
* frames per second. Then, the management of protocols is thread-safe: any
|
||||
* object can start/pause/stop protocols whithout problems.
|
||||
*/
|
||||
class ProtocolManager : public Singleton<ProtocolManager>
|
||||
{
|
||||
friend class Singleton<ProtocolManager>;
|
||||
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Function that processes incoming events.
|
||||
* This function is called by the network manager each time there is an
|
||||
* incoming packet.
|
||||
* incoming packet.
|
||||
*/
|
||||
virtual void notifyEvent(Event* event);
|
||||
/*!
|
||||
/*!
|
||||
* \brief WILL BE COMMENTED LATER
|
||||
*/
|
||||
virtual void sendMessage(Protocol* sender, const NetworkString& message);
|
||||
/*!
|
||||
/*!
|
||||
* \brief WILL BE COMMENTED LATER
|
||||
*/
|
||||
virtual void sendMessage(Protocol* sender, STKPeer* peer, const NetworkString& message);
|
||||
/*!
|
||||
/*!
|
||||
* \brief WILL BE COMMENTED LATER
|
||||
*/
|
||||
virtual void sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message);
|
||||
|
||||
/*!
|
||||
|
||||
/*!
|
||||
* \brief Asks the manager to start a protocol.
|
||||
* This function will store the request, and process it at a time it is
|
||||
* thread-safe.
|
||||
@ -123,48 +122,48 @@ class ProtocolManager : public Singleton<ProtocolManager>
|
||||
* \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
|
||||
*
|
||||
* 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
|
||||
* to update themselves. Finally processes stored requests about
|
||||
* starting, stoping, pausing etc... protocols.
|
||||
* This function is called by a thread as often as possible.
|
||||
* This function is not FPS-dependant.
|
||||
*/
|
||||
virtual void update();
|
||||
|
||||
/*!
|
||||
|
||||
/*!
|
||||
* \brief Get the number of protocols running.
|
||||
* \return The number of protocols that are actually running.
|
||||
*/
|
||||
@ -172,13 +171,13 @@ class ProtocolManager : public Singleton<ProtocolManager>
|
||||
/*!
|
||||
* \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.
|
||||
* \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.
|
||||
* \return The state of the protocol.
|
||||
*/
|
||||
virtual PROTOCOL_STATE getProtocolState(Protocol* protocol);
|
||||
/*!
|
||||
@ -187,29 +186,35 @@ class ProtocolManager : public Singleton<ProtocolManager>
|
||||
* \return The id of the protocol pointed by the protocol parameter.
|
||||
*/
|
||||
virtual uint32_t getProtocolID(Protocol* protocol);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Get a protocol using his id.
|
||||
* \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();
|
||||
|
||||
|
||||
protected:
|
||||
// protected functions
|
||||
/*!
|
||||
/*!
|
||||
* \brief Constructor
|
||||
*/
|
||||
ProtocolManager();
|
||||
/*!
|
||||
/*!
|
||||
* \brief Destructor
|
||||
*/
|
||||
virtual ~ProtocolManager();
|
||||
@ -221,7 +226,7 @@ class ProtocolManager : public Singleton<ProtocolManager>
|
||||
* \param protocol_info : The protocol info that needs an id.
|
||||
*/
|
||||
void assignProtocolId(ProtocolInfo* protocol_info);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Starts a protocol.
|
||||
* Add the protocol info to the m_protocols vector.
|
||||
@ -252,11 +257,11 @@ class ProtocolManager : public Singleton<ProtocolManager>
|
||||
* \param protocol : ProtocolInfo concerned.
|
||||
*/
|
||||
virtual void protocolTerminated(ProtocolInfo protocol);
|
||||
|
||||
|
||||
// protected members
|
||||
/*!
|
||||
/*!
|
||||
* \brief Contains the running protocols.
|
||||
* This stores the protocols that are either running or paused, their
|
||||
* This stores the protocols that are either running or paused, their
|
||||
* state and their unique id.
|
||||
*/
|
||||
std::vector<ProtocolInfo> m_protocols;
|
||||
@ -268,13 +273,13 @@ class ProtocolManager : public Singleton<ProtocolManager>
|
||||
* \brief Contains the requests to start/stop etc... protocols.
|
||||
*/
|
||||
std::vector<ProtocolRequest> m_requests;
|
||||
/*! \brief The next id to assign to a protocol.
|
||||
* This value is incremented by 1 each time a protocol is started.
|
||||
/*! \brief The next id to assign to a protocol.
|
||||
* This value is incremented by 1 each time a protocol is started.
|
||||
* If a protocol has an id lower than this value, it means that it have
|
||||
* been formerly started.
|
||||
* been formerly started.
|
||||
*/
|
||||
uint32_t m_next_protocol_id;
|
||||
|
||||
|
||||
// mutexes:
|
||||
/*! Used to ensure that the event queue is used thread-safely. */
|
||||
pthread_mutex_t m_events_mutex;
|
||||
@ -286,10 +291,10 @@ class ProtocolManager : public Singleton<ProtocolManager>
|
||||
pthread_mutex_t m_id_mutex;
|
||||
/*! Used when need to quit.*/
|
||||
pthread_mutex_t m_exit_mutex;
|
||||
|
||||
|
||||
/*! Update thread.*/
|
||||
pthread_t* m_update_thread;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // PROTOCOL_MANAGER_HPP
|
||||
|
@ -4,10 +4,10 @@
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
ClientLobbyRoomProtocol::ClientLobbyRoomProtocol(const TransportAddress& server_address)
|
||||
: LobbyRoomProtocol(NULL)
|
||||
{
|
||||
m_server_address = server_address;
|
||||
ClientLobbyRoomProtocol::ClientLobbyRoomProtocol(const TransportAddress& server_address)
|
||||
: LobbyRoomProtocol(NULL)
|
||||
{
|
||||
m_server_address = server_address;
|
||||
m_server = NULL;
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ void ClientLobbyRoomProtocol::notifyEvent(Event* event)
|
||||
assert(event->data.size()); // assert that data isn't empty
|
||||
Log::verbose("ClientLobbyRoomProtocol", "Message from %u : \"%s\"", event->peer->getAddress(), event->data.c_str());
|
||||
uint8_t message_type = event->data.getAndRemoveUInt8();
|
||||
|
||||
|
||||
if (message_type == 0x01) // new player connected
|
||||
newPlayer(event);
|
||||
else if (message_type == 0x02) // player disconnected
|
||||
@ -102,7 +102,7 @@ void ClientLobbyRoomProtocol::update()
|
||||
|
||||
/*! \brief Called when a new player is connected to the server
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 5 6 7
|
||||
* ------------------------------------------------
|
||||
@ -120,9 +120,9 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
|
||||
uint32_t global_id = event->data.gui32(1);
|
||||
|
||||
NetworkPlayerProfile profile;
|
||||
profile.kart_name = "";
|
||||
profile.race_id = event->data.gui8(6);
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile();
|
||||
profile->kart_name = "";
|
||||
profile->race_id = event->data.gui8(6);
|
||||
|
||||
if (global_id == CurrentOnlineUser::get()->getUserID())
|
||||
{
|
||||
@ -131,7 +131,7 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
else
|
||||
{
|
||||
Log::verbose("ClientLobbyRoomProtocol", "New player connected.");
|
||||
profile.user_profile = new OnlineUser(global_id);
|
||||
profile->user_profile = new OnlineUser(global_id);
|
||||
m_setup->addPlayer(profile);
|
||||
}
|
||||
}
|
||||
@ -140,7 +140,7 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
|
||||
/*! \brief Called when a new player is disconnected
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 2
|
||||
* -------------------------
|
||||
@ -170,7 +170,7 @@ void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event)
|
||||
|
||||
/*! \brief Called when the server accepts the connection.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 2 3 7 8 12
|
||||
* ----------------------------------------------------------
|
||||
@ -186,15 +186,15 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkPlayerProfile profile;
|
||||
profile.kart_name = "";
|
||||
profile.race_id = event->data.gui8(1);
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile();
|
||||
profile->kart_name = "";
|
||||
profile->race_id = event->data.gui8(1);
|
||||
uint32_t token = event->data.gui32(3);
|
||||
uint32_t global_id = event->data.gui32(8);
|
||||
if (global_id == CurrentOnlineUser::get()->getUserID())
|
||||
{
|
||||
Log::info("ClientLobbyRoomProtocol", "The server accepted the connection.");
|
||||
profile.user_profile = CurrentOnlineUser::get();
|
||||
profile->user_profile = CurrentOnlineUser::get();
|
||||
m_setup->addPlayer(profile);
|
||||
event->peer->setClientServerToken(token);
|
||||
m_server = event->peer;
|
||||
@ -206,7 +206,7 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
|
||||
/*! \brief Called when the server refuses the connection.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 2
|
||||
* --------------------
|
||||
@ -240,7 +240,7 @@ void ClientLobbyRoomProtocol::connectionRefused(Event* event)
|
||||
|
||||
/*! \brief Called when the server refuses the kart selection request.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 2
|
||||
* --------------------
|
||||
@ -272,11 +272,11 @@ void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when the server refuses the kart selection request.
|
||||
/*! \brief Called when the server tells to update a player's kart.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 2 3 N+3
|
||||
* Byte 0 1 2 3 N+3
|
||||
* ------------------------------------------------
|
||||
* Size | 1 | 1 | 1 | N |
|
||||
* Data | 1 | race id | N (kart name size) | kart name |
|
||||
@ -284,9 +284,24 @@ void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event)
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event)
|
||||
{
|
||||
if (event->data[0] != 1)
|
||||
if (event->data.size() < 3 || event->data[0] != 1)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected.");
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a kart selection update wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
uint8_t player_id = event->data[1];
|
||||
uint8_t kart_name_length = event->data[2];
|
||||
std::string data = event->data.getString(3);
|
||||
if (data.size() != kart_name_length)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "Kart names sizes differ: told: %d, real: %d.", kart_name_length, data.size());
|
||||
return;
|
||||
}
|
||||
if (!m_setup->isKartAvailable(data))
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "The updated kart is taken already.");
|
||||
}
|
||||
m_setup->setPlayerKart(player_id, data);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -8,15 +8,15 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
public:
|
||||
ClientLobbyRoomProtocol(const TransportAddress& server_address);
|
||||
virtual ~ClientLobbyRoomProtocol();
|
||||
|
||||
|
||||
void requestKartSelection(std::string kart_name);
|
||||
void sendMessage(std::string message);
|
||||
|
||||
|
||||
virtual void notifyEvent(Event* event);
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
void newPlayer(Event* event);
|
||||
void disconnectedPlayer(Event* event);
|
||||
@ -25,9 +25,9 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
void kartSelectionRefused(Event* event);
|
||||
void kartSelectionUpdate(Event* event);
|
||||
|
||||
TransportAddress m_server_address;
|
||||
TransportAddress m_server_address;
|
||||
STKPeer* m_server;
|
||||
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "network/protocols/get_peer_address.hpp"
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/http_functions.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
@ -47,7 +48,7 @@ void GetPeerAddress::update()
|
||||
{
|
||||
if (m_state == NONE)
|
||||
{
|
||||
|
||||
|
||||
HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector->setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector->setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "network/protocols/hide_public_address.hpp"
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "network/protocols/request_connection.hpp"
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
@ -53,7 +54,7 @@ void RequestConnection::update()
|
||||
Log::error("RequestConnection", "Fail to make a request.");
|
||||
}
|
||||
m_state = DONE;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case DONE:
|
||||
|
@ -46,62 +46,17 @@ void ServerLobbyRoomProtocol::notifyEvent(Event* event)
|
||||
uint8_t message_type;
|
||||
message_type = event->data.getAndRemoveUInt8();
|
||||
Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type);
|
||||
if (message_type == 1) // player requesting connection
|
||||
{
|
||||
if (event->data.size() != 5 || event->data[0] != 4)
|
||||
{
|
||||
Log::warn("LobbyRoomProtocol", "A player is sending a badly formated message. Size is %d and first byte %d", event->data.size(), event->data[0]);
|
||||
return;
|
||||
}
|
||||
Log::verbose("LobbyRoomProtocol", "New player.");
|
||||
int player_id = 0;
|
||||
player_id = event->data.getUInt32(1);
|
||||
// can we add the player ?
|
||||
if (m_setup->getPlayerCount() < 16) // accept player
|
||||
{
|
||||
// add the player to the game setup
|
||||
while(m_setup->getProfile(m_next_id)!=NULL)
|
||||
m_next_id++;
|
||||
NetworkPlayerProfile profile;
|
||||
profile.race_id = m_next_id;
|
||||
profile.kart_name = "";
|
||||
profile.user_profile = new OnlineUser("Unnamed Player");
|
||||
m_setup->addPlayer(profile);
|
||||
// notify everybody that there is a new player
|
||||
NetworkString message;
|
||||
// new player (1) -- size of id -- id -- size of local id -- local id;
|
||||
message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id);
|
||||
m_listener->sendMessageExcept(this, event->peer, message);
|
||||
// send a message to the one that asked to connect
|
||||
NetworkString message_ack;
|
||||
// 0b10000001 (connection success) ;
|
||||
RandomGenerator token_generator;
|
||||
// use 4 random numbers because rand_max is probably 2^15-1.
|
||||
uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<16) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<8) & 0xff) +
|
||||
((token_generator.get(RAND_MAX) & 0xff)));
|
||||
// connection success (129) -- size of token -- token
|
||||
message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id);
|
||||
m_listener->sendMessage(this, event->peer, message_ack);
|
||||
} // accept player
|
||||
else // refuse the connection with code 0 (too much players)
|
||||
{
|
||||
NetworkString message;
|
||||
message.ai8(0x80); // 128 means connection refused
|
||||
message.ai8(1); // 1 bytes for the error code
|
||||
message.ai8(0); // 0 = too much players
|
||||
// send only to the peer that made the request
|
||||
m_listener->sendMessage(this, event->peer, message);
|
||||
}
|
||||
}
|
||||
if (message_type == 0x01) // player requesting connection
|
||||
connectionRequested(event);
|
||||
if (message_type == 0x02) // player requesting kart selection
|
||||
kartSelectionRequested(event);
|
||||
} // if (event->type == EVENT_TYPE_MESSAGE)
|
||||
else if (event->type == EVENT_TYPE_CONNECTED)
|
||||
{
|
||||
} // if (event->type == EVENT_TYPE_CONNECTED)
|
||||
else if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
{
|
||||
|
||||
kartDisconnected(event);
|
||||
} // if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
}
|
||||
|
||||
@ -188,3 +143,137 @@ void ServerLobbyRoomProtocol::update()
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ServerLobbyRoomProtocol::kartDisconnected(Event* event)
|
||||
{
|
||||
if (event->peer->getPlayerProfile() != NULL) // others knew him
|
||||
{
|
||||
NetworkString msg;
|
||||
msg.ai8(0x02).ai8(1).ai8(event->peer->getPlayerProfile()->race_id);
|
||||
m_listener->sendMessage(this, msg);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when a player asks for a connection.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 5
|
||||
* ------------------------
|
||||
* Size | 1 | 4 |
|
||||
* Data | 4 | global player id |
|
||||
* ------------------------
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
{
|
||||
if (event->data.size() != 5 || event->data[0] != 4)
|
||||
{
|
||||
Log::warn("ServerLobbyRoomProtocol", "The server is sending a badly formated message. Size is %d and first byte %d", event->data.size(), event->data[0]);
|
||||
return;
|
||||
}
|
||||
Log::verbose("ServerLobbyRoomProtocol", "New player.");
|
||||
int player_id = 0;
|
||||
player_id = event->data.getUInt32(1);
|
||||
// can we add the player ?
|
||||
if (m_setup->getPlayerCount() < 16) // accept player
|
||||
{
|
||||
// add the player to the game setup
|
||||
while(m_setup->getProfile(m_next_id)!=NULL)
|
||||
m_next_id++;
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile();
|
||||
profile->race_id = m_next_id;
|
||||
profile->kart_name = "";
|
||||
profile->user_profile = new OnlineUser("Unnamed Player");
|
||||
m_setup->addPlayer(profile);
|
||||
event->peer->setPlayerProfile(profile);
|
||||
// notify everybody that there is a new player
|
||||
NetworkString message;
|
||||
// new player (1) -- size of id -- id -- size of local id -- local id;
|
||||
message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id);
|
||||
m_listener->sendMessageExcept(this, event->peer, message);
|
||||
// send a message to the one that asked to connect
|
||||
NetworkString message_ack;
|
||||
// 0b10000001 (connection success) ;
|
||||
RandomGenerator token_generator;
|
||||
// use 4 random numbers because rand_max is probably 2^15-1.
|
||||
uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<16) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<8) & 0xff) +
|
||||
((token_generator.get(RAND_MAX) & 0xff)));
|
||||
// connection success (129) -- size of token -- token
|
||||
message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id);
|
||||
m_listener->sendMessage(this, event->peer, message_ack);
|
||||
} // accept player
|
||||
else // refuse the connection with code 0 (too much players)
|
||||
{
|
||||
NetworkString message;
|
||||
message.ai8(0x80); // 128 means connection refused
|
||||
message.ai8(1); // 1 bytes for the error code
|
||||
message.ai8(0); // 0 = too much players
|
||||
// send only to the peer that made the request
|
||||
m_listener->sendMessage(this, event->peer, message);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when a player asks to select a kart.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 5 6 N+6
|
||||
* ---------------------------------------------------
|
||||
* Size | 1 | 4 | 1 | N |
|
||||
* Data | 4 | priv token | N (kart name size) | kart name |
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
{
|
||||
if (event->data.size() < 6 || event->data[0] != 4)
|
||||
{
|
||||
Log::warn("ServerLobbyRoomProtocol", "The server is sending a badly "
|
||||
"formated message. Size is %d and first byte %d",
|
||||
event->data.size(), event->data[0]);
|
||||
return;
|
||||
}
|
||||
uint32_t token = event->data.gui32(1);
|
||||
if (token != event->peer->getClientServerToken())
|
||||
{
|
||||
Log::warn("ServerLobbyRoomProtocol", "Peer sending bad token. Request "
|
||||
"aborted.");
|
||||
return;
|
||||
}
|
||||
uint8_t kart_name_size = event->data.gui8(5);
|
||||
std::string kart_name = event->data.gs(6);
|
||||
if (kart_name.size() != kart_name_size)
|
||||
{
|
||||
Log::error("ServerLobbyRoomProtocol", "Kart names sizes differ: told:"
|
||||
"%d, real: %d.", kart_name_size, kart_name.size());
|
||||
return;
|
||||
}
|
||||
if (!m_setup->isKartAvailable(kart_name))
|
||||
{
|
||||
NetworkString answer;
|
||||
answer.ai8(0x82).ai8(1).ai8(0); // kart is already taken
|
||||
m_listener->sendMessage(this, event->peer, answer);
|
||||
return;
|
||||
}
|
||||
// check if this kart is authorized
|
||||
if (!m_setup->isKartAllowed(kart_name))
|
||||
{
|
||||
NetworkString answer;
|
||||
answer.ai8(0x82).ai8(1).ai8(1); // kart is not authorized
|
||||
m_listener->sendMessage(this, event->peer, answer);
|
||||
return;
|
||||
}
|
||||
// send a kart update to everyone
|
||||
NetworkString answer;
|
||||
// kart update (3), 1, race id
|
||||
answer.ai8(0x03).ai8(1).ai8(event->peer->getPlayerProfile()->race_id);
|
||||
// kart name size, kart name
|
||||
answer.ai8(kart_name.size()).as(kart_name);
|
||||
m_listener->sendMessage(this, answer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -8,18 +8,22 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
public:
|
||||
ServerLobbyRoomProtocol();
|
||||
virtual ~ServerLobbyRoomProtocol();
|
||||
|
||||
|
||||
virtual void notifyEvent(Event* event);
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
|
||||
protected:
|
||||
void kartDisconnected(Event* event);
|
||||
void connectionRequested(Event* event);
|
||||
void kartSelectionRequested(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;
|
||||
TransportAddress m_public_address;
|
||||
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
|
@ -25,13 +25,14 @@
|
||||
STKPeer::STKPeer()
|
||||
{
|
||||
m_peer = NULL;
|
||||
m_player_profile = NULL;
|
||||
}
|
||||
|
||||
STKPeer::~STKPeer()
|
||||
{
|
||||
if (m_peer)
|
||||
{
|
||||
//free(m_peer);
|
||||
free(m_peer);
|
||||
m_peer = NULL;
|
||||
}
|
||||
}
|
||||
@ -39,15 +40,15 @@ STKPeer::~STKPeer()
|
||||
bool STKPeer::connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data)
|
||||
{
|
||||
ENetAddress address;
|
||||
address.host =
|
||||
address.host =
|
||||
((host.ip & 0xff000000) >> 24)
|
||||
+ ((host.ip & 0x00ff0000) >> 8)
|
||||
+ ((host.ip & 0x0000ff00) << 8)
|
||||
+ ((host.ip & 0x000000ff) << 24); // because ENet wants little endian
|
||||
address.port = host.port;
|
||||
|
||||
|
||||
ENetPeer* peer = enet_host_connect(localhost->m_host, &address, 2, 0);
|
||||
if (peer == NULL)
|
||||
if (peer == NULL)
|
||||
{
|
||||
Log::error("STKPeer", "Could not try to connect to server.\n");
|
||||
return false;
|
||||
@ -65,7 +66,7 @@ void STKPeer::sendPacket(NetworkString const& data)
|
||||
{
|
||||
Log::verbose("STKPeer", "sending packet of size %d to %i.%i.%i.%i:%i", data.size(), (m_peer->address.host>>0)&0xff,(m_peer->address.host>>8)&0xff,(m_peer->address.host>>16)&0xff,(m_peer->address.host>>24)&0xff,m_peer->address.port);
|
||||
ENetPacket* packet = enet_packet_create(data.c_str(), data.size()+1,ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
|
||||
enet_peer_send(m_peer, 0, packet);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "network/stk_host.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include <enet/enet.h>
|
||||
|
||||
class STKPeer
|
||||
@ -29,9 +30,9 @@ class STKPeer
|
||||
public:
|
||||
STKPeer();
|
||||
virtual ~STKPeer();
|
||||
|
||||
|
||||
virtual void sendPacket(const NetworkString& data);
|
||||
|
||||
|
||||
static bool connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data);
|
||||
|
||||
void disconnect();
|
||||
@ -39,16 +40,19 @@ class STKPeer
|
||||
bool isConnected() 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; }
|
||||
|
||||
uint32_t getAddress() const;
|
||||
uint16_t getPort() const;
|
||||
uint32_t getClientServerToken() const { return m_client_server_token; }
|
||||
bool isClientServerTokenSet() const { return m_token_set; }
|
||||
|
||||
NetworkPlayerProfile* getPlayerProfile() { return m_player_profile; }
|
||||
|
||||
bool operator==(const ENetPeer* peer) const;
|
||||
|
||||
|
||||
protected:
|
||||
ENetPeer* m_peer;
|
||||
NetworkPlayerProfile* m_player_profile;
|
||||
uint32_t m_client_server_token;
|
||||
bool m_token_set;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user