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"
|
||||
|
||||
@ -55,6 +56,14 @@ void* waitInput(void* data)
|
||||
{
|
||||
ProtocolManager::getInstance()->requestStart(new ConnectToServer(n));
|
||||
}
|
||||
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;
|
||||
|
@ -74,6 +74,15 @@ Event::Event(ENetEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
Event::Event(const Event& event)
|
||||
{
|
||||
m_packet = NULL;
|
||||
data = event.data;
|
||||
// copy the peer
|
||||
peer = new STKPeer(*event.peer);
|
||||
type = event.type;
|
||||
}
|
||||
|
||||
Event::~Event()
|
||||
{
|
||||
}
|
||||
|
@ -51,6 +51,10 @@ 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.
|
||||
*/
|
||||
|
@ -34,7 +34,7 @@ GameSetup::~GameSetup()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GameSetup::addPlayer(NetworkPlayerProfile profile)
|
||||
void GameSetup::addPlayer(NetworkPlayerProfile* profile)
|
||||
{
|
||||
m_players.push_back(profile);
|
||||
}
|
||||
@ -45,8 +45,9 @@ 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;
|
||||
@ -61,7 +62,7 @@ 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.");
|
||||
@ -73,13 +74,27 @@ 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;
|
||||
@ -91,9 +106,9 @@ 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;
|
||||
|
@ -52,17 +52,20 @@ class 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)
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
@ -259,6 +260,7 @@ 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;
|
||||
}
|
||||
|
||||
@ -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,12 +26,11 @@
|
||||
#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.
|
||||
@ -189,11 +188,17 @@ class ProtocolManager : public Singleton<ProtocolManager>
|
||||
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.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
@ -272,7 +272,7 @@ 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 :
|
||||
@ -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);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -14,6 +14,10 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -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