adding features in the client lobby room protocol, separating client and server lobby room protocols in their own files to have clearer code
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13162 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
8ca4b62038
commit
212b77fef3
Binary file not shown.
@ -150,6 +150,8 @@ src/network/protocols/get_peer_address.cpp
|
||||
src/network/protocols/get_public_address.cpp
|
||||
src/network/protocols/hide_public_address.cpp
|
||||
src/network/protocols/lobby_room_protocol.cpp
|
||||
src/network/protocols/client_lobby_room_protocol.cpp
|
||||
src/network/protocols/server_lobby_room_protocol.cpp
|
||||
src/network/protocols/ping_protocol.cpp
|
||||
src/network/protocols/quick_join_protocol.cpp
|
||||
src/network/protocols/request_connection.cpp
|
||||
@ -421,6 +423,8 @@ src/network/protocols/get_peer_address.hpp
|
||||
src/network/protocols/get_public_address.hpp
|
||||
src/network/protocols/hide_public_address.hpp
|
||||
src/network/protocols/lobby_room_protocol.hpp
|
||||
src/network/protocols/client_lobby_room_protocol.hpp
|
||||
src/network/protocols/server_lobby_room_protocol.hpp
|
||||
src/network/protocols/ping_protocol.hpp
|
||||
src/network/protocols/quick_join_protocol.hpp
|
||||
src/network/protocols/request_connection.hpp
|
||||
|
14
src/main.cpp
14
src/main.cpp
@ -172,7 +172,7 @@
|
||||
#include "network/client_network_manager.hpp"
|
||||
#include "network/server_network_manager.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/protocols/lobby_room_protocol.hpp"
|
||||
#include "network/protocols/server_lobby_room_protocol.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "race/grand_prix_manager.hpp"
|
||||
#include "race/highscore_manager.hpp"
|
||||
@ -406,13 +406,11 @@ void cmdLineHelp (char* invocation)
|
||||
// " --history=n Replay history file 'history.dat' using:\n"
|
||||
// " n=1: recorded positions\n"
|
||||
// " n=2: recorded key strokes\n"
|
||||
//" --server[=port] This is the server (running on the specified "
|
||||
// "port).\n"
|
||||
//" --client=ip This is a client, connect to the specified ip"
|
||||
// " address.\n"
|
||||
//" --port=n Port number to use.\n"
|
||||
//" --numclients=n Number of clients to wait for (server "
|
||||
// "only).\n"
|
||||
" --server Start a server (not a playing client).\n"
|
||||
" --login=s Automatically sign in (set the login).\n"
|
||||
" --password=s Automatically sign in (set the password).\n"
|
||||
" --port=n Port number to use.\n"
|
||||
" --max-players=n Maximum number of clients (server only).\n"
|
||||
" --no-console Does not write messages in the console but to\n"
|
||||
" stdout.log.\n"
|
||||
" --console Write messages in the console and files\n"
|
||||
|
@ -57,7 +57,8 @@ void* waitInput(void* data)
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkString msg("\0\0");
|
||||
NetworkString msg;
|
||||
msg.ai8(0);
|
||||
msg += str;
|
||||
NetworkManager::getInstance()->getPeers()[0]->sendPacket(msg);
|
||||
}
|
||||
@ -71,6 +72,7 @@ void* waitInput(void* data)
|
||||
ClientNetworkManager::ClientNetworkManager()
|
||||
{
|
||||
m_thread_keyboard = NULL;
|
||||
m_connected = false;
|
||||
}
|
||||
|
||||
ClientNetworkManager::~ClientNetworkManager()
|
||||
|
@ -35,11 +35,14 @@ class ClientNetworkManager : public NetworkManager
|
||||
|
||||
STKPeer* getPeer();
|
||||
virtual bool isServer() { return false; }
|
||||
void setConnected(bool value) { m_connected = value; }
|
||||
bool isConnected() { return m_connected; }
|
||||
|
||||
protected:
|
||||
ClientNetworkManager();
|
||||
virtual ~ClientNetworkManager();
|
||||
|
||||
bool m_connected; //!< Is the user connected to a server
|
||||
pthread_t* m_thread_keyboard;
|
||||
};
|
||||
|
||||
|
@ -37,6 +37,7 @@ Event::Event(ENetEvent* event)
|
||||
type = EVENT_TYPE_MESSAGE;
|
||||
break;
|
||||
default:
|
||||
type = EVENT_TYPE_MESSAGE;
|
||||
break;
|
||||
}
|
||||
if (type == EVENT_TYPE_MESSAGE)
|
||||
|
@ -41,7 +41,7 @@ void GameSetup::addPlayer(NetworkPlayerProfile profile)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GameSetup::removePlayer(uint32_t id)
|
||||
bool GameSetup::removePlayer(uint32_t id)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_players.size(); i++)
|
||||
{
|
||||
@ -49,14 +49,15 @@ void GameSetup::removePlayer(uint32_t id)
|
||||
{
|
||||
m_players.erase(m_players.begin()+i, m_players.begin()+i+1);
|
||||
Log::verbose("GameSetup", "Removed a player from the game setup.");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GameSetup::removePlayer(uint8_t id)
|
||||
bool GameSetup::removePlayer(uint8_t id)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_players.size(); i++)
|
||||
{
|
||||
@ -64,9 +65,10 @@ void GameSetup::removePlayer(uint8_t id)
|
||||
{
|
||||
m_players.erase(m_players.begin()+i, m_players.begin()+i+1);
|
||||
Log::verbose("GameSetup", "Removed a player from the game setup.");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -98,3 +100,13 @@ const NetworkPlayerProfile* GameSetup::getProfile(uint8_t id)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -52,13 +52,15 @@ class GameSetup
|
||||
virtual ~GameSetup();
|
||||
|
||||
void addPlayer(NetworkPlayerProfile profile); //!< Add a player.
|
||||
void removePlayer(uint32_t id); //!< Remove a player by id.
|
||||
void removePlayer(uint8_t id); //!< Remove a player by local id.
|
||||
bool removePlayer(uint32_t id); //!< Remove a player by id.
|
||||
bool removePlayer(uint8_t id); //!< Remove a player by local id.
|
||||
|
||||
int getPlayerCount() { return m_players.size(); }
|
||||
const NetworkPlayerProfile* getProfile(uint32_t id); //!< Get a profile by database id
|
||||
const NetworkPlayerProfile* getProfile(uint8_t id); //!< Get the profile by the lobby id
|
||||
|
||||
bool isKartAvailable(std::string kart_name);
|
||||
|
||||
protected:
|
||||
std::vector<NetworkPlayerProfile> m_players; //!< Information about players
|
||||
NetworkPlayerProfile m_self_profile; //!< Information about self (client only)
|
||||
|
@ -88,11 +88,14 @@ void NetworkManager::setManualSocketsMode(bool manual)
|
||||
|
||||
void NetworkManager::notifyEvent(Event* event)
|
||||
{
|
||||
Log::info("NetworkManager", "EVENT received");
|
||||
Log::info("NetworkManager", "EVENT received of type %d", (int)(event->type));
|
||||
switch (event->type)
|
||||
{
|
||||
case EVENT_TYPE_MESSAGE:
|
||||
Log::debug("NetworkManager", "Message, Sender : %i.%i.%i.%i, message = \"%s\"", event->peer->getAddress()>>24&0xff, event->peer->getAddress()>>16&0xff, event->peer->getAddress()>>8&0xff, event->peer->getAddress()&0xff, event->data.c_str());
|
||||
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:
|
||||
{
|
||||
@ -119,14 +122,19 @@ void NetworkManager::notifyEvent(Event* event)
|
||||
|
||||
Log::debug("NetworkManager", "Somebody is now disconnected. There are now %lu peers.", m_peers.size());
|
||||
|
||||
break;
|
||||
}
|
||||
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;
|
||||
|
||||
} 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;
|
||||
}
|
||||
ProtocolManager::getInstance()->notifyEvent(event);
|
||||
}
|
||||
|
@ -98,6 +98,14 @@ class NetworkString
|
||||
return *this;
|
||||
}
|
||||
inline NetworkString& ad(const double& value) { return addDouble(value); }
|
||||
|
||||
NetworkString& addString(const std::string& value)
|
||||
{
|
||||
m_string += value;
|
||||
return *this;
|
||||
}
|
||||
inline NetworkString& as(const std::string& value) { return addString(value); }
|
||||
|
||||
NetworkString& operator+=(NetworkString const& value)
|
||||
{
|
||||
m_string += value.m_string;
|
||||
|
292
src/network/protocols/client_lobby_room_protocol.cpp
Normal file
292
src/network/protocols/client_lobby_room_protocol.cpp
Normal file
@ -0,0 +1,292 @@
|
||||
#include "network/protocols/client_lobby_room_protocol.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
ClientLobbyRoomProtocol::ClientLobbyRoomProtocol(const TransportAddress& server_address)
|
||||
: LobbyRoomProtocol(NULL)
|
||||
{
|
||||
m_server_address = server_address;
|
||||
m_server = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ClientLobbyRoomProtocol::~ClientLobbyRoomProtocol()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::setup()
|
||||
{
|
||||
m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup
|
||||
m_state = NONE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::requestKartSelection(std::string kart_name)
|
||||
{
|
||||
NetworkString request;
|
||||
// 0x02 : kart selection request, size_token (4), token, size kart name, kart name
|
||||
request.ai8(0x02).ai8(4).ai32(m_server->getClientServerToken()).ai8(kart_name.size()).as(kart_name);
|
||||
m_listener->sendMessage(this, request);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::notifyEvent(Event* event)
|
||||
{
|
||||
assert(m_setup); // assert that the setup exists
|
||||
if (event->type == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
assert(event->data.size()); // assert that data isn't empty
|
||||
Log::verbose("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
|
||||
disconnectedPlayer(event);
|
||||
else if (message_type == 0x03) // kart selection update
|
||||
kartSelectionUpdate(event);
|
||||
else if (message_type == 0x80) // connection refused
|
||||
connectionRefused(event);
|
||||
else if (message_type == 0x81) // connection accepted
|
||||
connectionAccepted(event);
|
||||
else if (message_type == 0x82) // kart selection refused
|
||||
kartSelectionRefused(event);
|
||||
|
||||
} // message
|
||||
else if (event->type == EVENT_TYPE_CONNECTED)
|
||||
{
|
||||
} // connection
|
||||
else if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
{
|
||||
} // disconnection
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::update()
|
||||
{
|
||||
switch (m_state)
|
||||
{
|
||||
case NONE:
|
||||
if (NetworkManager::getInstance()->isConnectedTo(m_server_address))
|
||||
{
|
||||
m_state = LINKED;
|
||||
}
|
||||
break;
|
||||
case LINKED:
|
||||
{
|
||||
NetworkString ns;
|
||||
// 1 (connection request), 4 (size of id), global id
|
||||
ns.ai8(1).ai8(4).ai32(CurrentOnlineUser::get()->getUserID());
|
||||
m_listener->sendMessage(this, ns);
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
} break;
|
||||
case REQUESTING_CONNECTION:
|
||||
break;
|
||||
case CONNECTED:
|
||||
break;
|
||||
case DONE:
|
||||
m_listener->requestTerminate(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \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
|
||||
* ------------------------------------------------
|
||||
* Size | 1 | 4 | 1 | 1 |
|
||||
* Data | 4 | player global id | 1 | 0 <= race id < 16 |
|
||||
* ------------------------------------------------
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
{
|
||||
if (event->data.size() != 7 || event->data[0] != 4 || event->data[5] != 1) // 7 bytes remains now
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a new player wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t global_id = event->data.gui32(1);
|
||||
|
||||
NetworkPlayerProfile profile;
|
||||
profile.kart_name = "";
|
||||
profile.race_id = event->data.gui8(6);
|
||||
|
||||
if (global_id == CurrentOnlineUser::get()->getUserID())
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "The server notified me that i'm a new player in the room (not normal).");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::verbose("ClientLobbyRoomProtocol", "New player connected.");
|
||||
profile.user_profile = new OnlineUser(global_id);
|
||||
m_setup->addPlayer(profile);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when a new player is disconnected
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 2
|
||||
* -------------------------
|
||||
* Size | 1 | 1 |
|
||||
* Data | 1 | 0 <= race id < 16 |
|
||||
* -------------------------
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event)
|
||||
{
|
||||
if (event->data.size() != 2 || event->data[0] != 1)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a new player wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
uint8_t id = event->data[1];
|
||||
if (m_setup->removePlayer(id))
|
||||
{
|
||||
Log::info("ClientLobbyRoomProtocol", "Peer removed successfully.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "The disconnected peer wasn't known.");
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \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
|
||||
* ----------------------------------------------------------
|
||||
* Size | 1 | 1 | 1 | 4 | 1 | 4 |
|
||||
* Data | 1 | 0 <= race id < 16 | 4 | priv token | 4 | global id |
|
||||
* ----------------------------------------------------------
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
{
|
||||
if (event->data.size() != 12 || event->data[0] != 1 || event->data[2] != 4 || event->data[7] != 4) // 12 bytes remains now
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying an accepted connection wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkPlayerProfile profile;
|
||||
profile.kart_name = "";
|
||||
profile.race_id = event->data.gui8(1);
|
||||
uint32_t token = event->data.gui32(3);
|
||||
uint32_t global_id = event->data.gui32(8);
|
||||
if (global_id == CurrentOnlineUser::get()->getUserID())
|
||||
{
|
||||
Log::info("ClientLobbyRoomProtocol", "The server accepted the connection.");
|
||||
profile.user_profile = CurrentOnlineUser::get();
|
||||
m_setup->addPlayer(profile);
|
||||
event->peer->setClientServerToken(token);
|
||||
m_server = event->peer;
|
||||
m_state = CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when the server refuses the connection.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 2
|
||||
* --------------------
|
||||
* Size | 1 | 1 |
|
||||
* Data | 1 | refusal code |
|
||||
* --------------------
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::connectionRefused(Event* event)
|
||||
{
|
||||
if (event->data.size() != 2 || event->data[0] != 1) // 2 bytes remains now
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event->data[1]) // the second byte
|
||||
{
|
||||
case 0:
|
||||
Log::info("ClientLobbyRoomProtocol", "Connection refused : too many players.");
|
||||
break;
|
||||
case 1:
|
||||
Log::info("ClientLobbyRoomProtocol", "Connection refused : banned.");
|
||||
break;
|
||||
default:
|
||||
Log::info("ClientLobbyRoomProtocol", "Connection refused.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when the server refuses the kart selection request.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 2
|
||||
* --------------------
|
||||
* Size | 1 | 1 |
|
||||
* Data | 1 | refusal code |
|
||||
* --------------------
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event)
|
||||
{
|
||||
if (event->data.size() != 2 || event->data[0] != 1)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a refused kart selection wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event->data[1]) // the error code
|
||||
{
|
||||
case 0:
|
||||
Log::info("ClientLobbyRoomProtocol", "Kart selection refused : already taken.");
|
||||
break;
|
||||
case 1:
|
||||
Log::info("ClientLobbyRoomProtocol", "Kart selection refused : not available.");
|
||||
break;
|
||||
default:
|
||||
Log::info("ClientLobbyRoomProtocol", "Kart selection refused.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when the server refuses the kart selection request.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 2 3 N+3
|
||||
* ------------------------------------------------
|
||||
* Size | 1 | 1 | 1 | N |
|
||||
* Data | 1 | race id | N (kart name size) | kart name |
|
||||
* ------------------------------------------------
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event)
|
||||
{
|
||||
if (event->data[0] != 1)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
}
|
42
src/network/protocols/client_lobby_room_protocol.hpp
Normal file
42
src/network/protocols/client_lobby_room_protocol.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef CLIENT_LOBBY_ROOM_PROTOCOL_HPP
|
||||
#define CLIENT_LOBBY_ROOM_PROTOCOL_HPP
|
||||
|
||||
#include "network/protocols/lobby_room_protocol.hpp"
|
||||
|
||||
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);
|
||||
void connectionAccepted(Event* event); //!< Callback function on connection acceptation
|
||||
void connectionRefused(Event* event); //!< Callback function on connection refusal
|
||||
void kartSelectionRefused(Event* event);
|
||||
void kartSelectionUpdate(Event* event);
|
||||
|
||||
TransportAddress m_server_address;
|
||||
STKPeer* m_server;
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
LINKED,
|
||||
REQUESTING_CONNECTION,
|
||||
CONNECTED,
|
||||
DONE
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
||||
#endif // CLIENT_LOBBY_ROOM_PROTOCOL_HPP
|
@ -26,7 +26,7 @@
|
||||
#include "network/protocols/request_connection.hpp"
|
||||
#include "network/protocols/ping_protocol.hpp"
|
||||
#include "network/protocols/quick_join_protocol.hpp"
|
||||
#include "network/protocols/lobby_room_protocol.hpp"
|
||||
#include "network/protocols/client_lobby_room_protocol.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "utils/time.hpp"
|
||||
#include "utils/log.hpp"
|
||||
@ -159,6 +159,7 @@ void ConnectToServer::update()
|
||||
{
|
||||
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());
|
||||
ClientNetworkManager::getInstance()->setConnected(true);
|
||||
m_state = HIDING_ADDRESS;
|
||||
break;
|
||||
}
|
||||
@ -167,7 +168,8 @@ void ConnectToServer::update()
|
||||
== PROTOCOL_STATE_TERMINATED) // we have hidden our address
|
||||
{
|
||||
m_state = DONE;
|
||||
m_listener->requestStart(new ClientLobbyRoomProtocol(m_server_address));
|
||||
if (ClientNetworkManager::getInstance()->isConnected()) // lobby room protocol if we're connected only
|
||||
m_listener->requestStart(new ClientLobbyRoomProtocol(m_server_address));
|
||||
}
|
||||
break;
|
||||
case DONE:
|
||||
|
@ -18,23 +18,8 @@
|
||||
|
||||
#include "network/protocols/lobby_room_protocol.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/client_network_manager.hpp"
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
#include "network/protocols/connect_to_peer.hpp"
|
||||
#include "network/protocols/start_server.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
LobbyRoomProtocol::LobbyRoomProtocol(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_LOBBY_ROOM)
|
||||
LobbyRoomProtocol::LobbyRoomProtocol(CallbackObject* callback_object) :
|
||||
Protocol(callback_object, PROTOCOL_LOBBY_ROOM)
|
||||
{
|
||||
m_setup = NULL;
|
||||
}
|
||||
@ -44,298 +29,3 @@ LobbyRoomProtocol::LobbyRoomProtocol(CallbackObject* callback_object) : Protocol
|
||||
LobbyRoomProtocol::~LobbyRoomProtocol()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::setup()
|
||||
{
|
||||
m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup
|
||||
m_state = NONE;
|
||||
Log::info("ClientLobbyRoomProtocol", "Starting the protocol.");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ServerLobbyRoomProtocol::setup()
|
||||
{
|
||||
m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup
|
||||
m_next_id = 0;
|
||||
m_state = NONE;
|
||||
m_public_address.ip = 0;
|
||||
m_public_address.port = 0;
|
||||
Log::info("ServerLobbyRoomProtocol", "Starting the protocol.");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::notifyEvent(Event* event)
|
||||
{
|
||||
assert(m_setup); // assert that the setup exists
|
||||
if (event->type == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
assert(event->data.size()); // assert that data isn't empty
|
||||
Log::verbose("LobbyRoomProtocol", "Message from %u : \"%s\"", event->peer->getAddress(), event->data.c_str());
|
||||
uint8_t message_type = event->data.getAndRemoveUInt8();
|
||||
if (message_type == 1) // new player connected
|
||||
{
|
||||
if (event->data.size() != 7 || event->data[0] != 4 || event->data[5] != 1) // 7 bytes remains now
|
||||
{
|
||||
Log::error("LobbyRoomProtocol", "A message notifying a new player wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t global_id = event->data.gui32(1);
|
||||
|
||||
NetworkPlayerProfile profile;
|
||||
profile.kart_name = "";
|
||||
profile.race_id = event->data.gui8(6);
|
||||
|
||||
if (global_id == CurrentOnlineUser::get()->getUserID())
|
||||
{
|
||||
Log::error("LobbyRoomProtocol", "The server notified me that i'm a new player in the room (not normal).");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::verbose("LobbyRoomProtocol", "New player connected.");
|
||||
profile.user_profile = new OnlineUser(""); ///! INSERT THE ID OF THE PLAYER HERE (global_id)
|
||||
m_setup->addPlayer(profile);
|
||||
}
|
||||
} // new player connected
|
||||
else if (message_type == 0x81) // connection accepted
|
||||
{
|
||||
if (event->data.size() != 12 || event->data[0] != 1 || event->data[2] != 4 || event->data[7] != 4) // 12 bytes remains now
|
||||
{
|
||||
Log::error("LobbyRoomProtocol", "A message notifying an accepted connection wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkPlayerProfile profile;
|
||||
profile.kart_name = "";
|
||||
profile.race_id = event->data.gui8(1);
|
||||
uint32_t token = event->data.gui32(3);
|
||||
uint32_t global_id = event->data.gui32(8);
|
||||
if (global_id == CurrentOnlineUser::get()->getUserID())
|
||||
{
|
||||
Log::info("LobbyRoomProtocol", "The server accepted the connection.");
|
||||
profile.user_profile = CurrentOnlineUser::get();
|
||||
m_setup->addPlayer(profile);
|
||||
event->peer->setClientServerToken(token);
|
||||
m_state = CONNECTED;
|
||||
}
|
||||
} // connection accepted
|
||||
else if (message_type == 0x80) // connection refused
|
||||
{
|
||||
if (event->data.size() != 2 || event->data[0] != 1) // 2 bytes remains now
|
||||
{
|
||||
Log::error("LobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info("LobbyRoomProtocol", "The connection has been refused.");
|
||||
switch (event->data[1]) // the second byte
|
||||
{
|
||||
case 0:
|
||||
Log::info("LobbyRoomProtocol", "Too many clients in the race.");
|
||||
break;
|
||||
case 1:
|
||||
Log::info("LobbyRoomProtocol", "The host has banned you.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} // connection refused
|
||||
} // if (event->type == EVENT_TYPE_MESSAGE)
|
||||
else if (event->type == EVENT_TYPE_CONNECTED)
|
||||
{
|
||||
} // if (event->type == EVENT_TYPE_CONNECTED)
|
||||
else if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
{
|
||||
} // if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ServerLobbyRoomProtocol::notifyEvent(Event* event)
|
||||
{
|
||||
assert(m_setup); // assert that the setup exists
|
||||
if (event->type == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
assert(event->data.size()); // message not empty
|
||||
uint8_t message_type;
|
||||
message_type = event->data.getAndRemoveUInt8();
|
||||
Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type);
|
||||
if (message_type == 1) // player requesting connection
|
||||
{
|
||||
if (event->data.size() != 5 || event->data[0] != 4)
|
||||
{
|
||||
Log::warn("LobbyRoomProtocol", "A player is sending a badly formated message. Size is %d and first byte %d", event->data.size(), event->data[0]);
|
||||
return;
|
||||
}
|
||||
Log::verbose("LobbyRoomProtocol", "New player.");
|
||||
int player_id = 0;
|
||||
player_id = event->data.getUInt32(1);
|
||||
// can we add the player ?
|
||||
if (m_setup->getPlayerCount() < 16) // accept player
|
||||
{
|
||||
// add the player to the game setup
|
||||
while(m_setup->getProfile(m_next_id)!=NULL)
|
||||
m_next_id++;
|
||||
NetworkPlayerProfile profile;
|
||||
profile.race_id = m_next_id;
|
||||
profile.kart_name = "";
|
||||
profile.user_profile = new OnlineUser("Unnamed Player");
|
||||
m_setup->addPlayer(profile);
|
||||
// notify everybody that there is a new player
|
||||
NetworkString message;
|
||||
// new player (1) -- size of id -- id -- size of local id -- local id;
|
||||
message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id);
|
||||
m_listener->sendMessageExcept(this, event->peer, message);
|
||||
// send a message to the one that asked to connect
|
||||
NetworkString message_ack;
|
||||
// 0b10000001 (connection success) ;
|
||||
RandomGenerator token_generator;
|
||||
// use 4 random numbers because rand_max is probably 2^15-1.
|
||||
uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<16) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<8) & 0xff) +
|
||||
((token_generator.get(RAND_MAX) & 0xff)));
|
||||
// connection success (129) -- size of token -- token
|
||||
message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id);
|
||||
m_listener->sendMessage(this, event->peer, message_ack);
|
||||
} // accept player
|
||||
else // refuse the connection with code 0 (too much players)
|
||||
{
|
||||
NetworkString message;
|
||||
message.ai8(0x80); // 128 means connection refused
|
||||
message.ai8(1); // 1 bytes for the error code
|
||||
message.ai8(0); // 0 = too much players
|
||||
// send only to the peer that made the request
|
||||
m_listener->sendMessage(this, event->peer, message);
|
||||
}
|
||||
}
|
||||
} // if (event->type == EVENT_TYPE_MESSAGE)
|
||||
else if (event->type == EVENT_TYPE_CONNECTED)
|
||||
{
|
||||
} // if (event->type == EVENT_TYPE_CONNECTED)
|
||||
else if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
{
|
||||
|
||||
} // if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::update()
|
||||
{
|
||||
switch (m_state)
|
||||
{
|
||||
case NONE:
|
||||
if (NetworkManager::getInstance()->isConnectedTo(m_server_address))
|
||||
{
|
||||
m_state = LINKED;
|
||||
}
|
||||
break;
|
||||
case LINKED:
|
||||
{
|
||||
NetworkString ns;
|
||||
// 1 (connection request), 4 (size of id), global id
|
||||
ns.ai8(1).ai8(4).ai32(CurrentOnlineUser::get()->getUserID());
|
||||
m_listener->sendMessage(this, ns);
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
break;
|
||||
}
|
||||
case REQUESTING_CONNECTION:
|
||||
break;
|
||||
case CONNECTED:
|
||||
break;
|
||||
case DONE:
|
||||
m_listener->requestTerminate(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ServerLobbyRoomProtocol::update()
|
||||
{
|
||||
switch (m_state)
|
||||
{
|
||||
case NONE:
|
||||
m_current_protocol_id = m_listener->requestStart(new GetPublicAddress(&m_public_address));
|
||||
m_state = GETTING_PUBLIC_ADDRESS;
|
||||
break;
|
||||
case GETTING_PUBLIC_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
NetworkManager::getInstance()->setPublicAddress(m_public_address);
|
||||
m_current_protocol_id = m_listener->requestStart(new StartServer());
|
||||
m_state = LAUNCHING_SERVER;
|
||||
Log::debug("ServerLobbyRoomProtocol", "Public address known.");
|
||||
}
|
||||
break;
|
||||
case LAUNCHING_SERVER:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
m_state = WORKING;
|
||||
Log::info("ServerLobbyRoomProtocol", "Server setup");
|
||||
}
|
||||
break;
|
||||
case WORKING:
|
||||
{
|
||||
// first poll every 5 seconds
|
||||
static double last_poll_time = 0;
|
||||
if (Time::getRealTime() > last_poll_time+10.0)
|
||||
{
|
||||
last_poll_time = Time::getRealTime();
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector->setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector->setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector->setParameter("address",addr.ip);
|
||||
connector->setParameter("port",addr.port);
|
||||
connector->setParameter("action","poll-connection-requests");
|
||||
|
||||
const XMLNode * result = connector->getXMLFromPage();
|
||||
std::string rec_success;
|
||||
if(result->get("success", &rec_success))
|
||||
{
|
||||
if(rec_success == "yes")
|
||||
{
|
||||
const XMLNode * users_xml = result->getNode("users");
|
||||
uint32_t id = 0;
|
||||
for (unsigned int i = 0; i < users_xml->getNumNodes(); i++)
|
||||
{
|
||||
users_xml->getNode(i)->get("id", &id);
|
||||
Log::debug("ServerLobbyRoomProtocol", "User with id %d wants to connect.", id);
|
||||
m_incoming_peers_ids.push_back(id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("ServerLobbyRoomProtocol", "Error while reading the list.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("ServerLobbyRoomProtocol", "Cannot retrieve the list.");
|
||||
}
|
||||
}
|
||||
|
||||
// now
|
||||
for (unsigned int i = 0; i < m_incoming_peers_ids.size(); i++)
|
||||
{
|
||||
m_listener->requestStart(new ConnectToPeer(m_incoming_peers_ids[i]));
|
||||
}
|
||||
m_incoming_peers_ids.clear();
|
||||
|
||||
break;
|
||||
}
|
||||
case DONE:
|
||||
m_listener->requestTerminate(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
@ -44,59 +44,4 @@ class LobbyRoomProtocol : public Protocol
|
||||
GameSetup* m_setup; //!< The game setup.
|
||||
};
|
||||
|
||||
class ClientLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
{
|
||||
public:
|
||||
ClientLobbyRoomProtocol(const TransportAddress& server_address) : LobbyRoomProtocol(NULL)
|
||||
{ m_server_address = server_address;}
|
||||
virtual ~ClientLobbyRoomProtocol() {}
|
||||
|
||||
virtual void notifyEvent(Event* event);
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
void sendMessage(std::string message);
|
||||
|
||||
protected:
|
||||
TransportAddress m_server_address;
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
LINKED,
|
||||
REQUESTING_CONNECTION,
|
||||
CONNECTED,
|
||||
DONE
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
||||
class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
{
|
||||
public:
|
||||
ServerLobbyRoomProtocol() : LobbyRoomProtocol(NULL) {}
|
||||
virtual ~ServerLobbyRoomProtocol() {}
|
||||
|
||||
virtual void notifyEvent(Event* event);
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
protected:
|
||||
uint8_t m_next_id; //!< Next id to assign to a peer.
|
||||
std::vector<TransportAddress> m_peers;
|
||||
std::vector<uint32_t> m_incoming_peers_ids;
|
||||
uint32_t m_current_protocol_id;
|
||||
TransportAddress m_public_address;
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
GETTING_PUBLIC_ADDRESS,
|
||||
LAUNCHING_SERVER,
|
||||
WORKING,
|
||||
DONE
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
||||
#endif // LOBBY_ROOM_PROTOCOL_HPP
|
||||
|
190
src/network/protocols/server_lobby_room_protocol.cpp
Normal file
190
src/network/protocols/server_lobby_room_protocol.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
#include "network/protocols/server_lobby_room_protocol.hpp"
|
||||
|
||||
#include "network/server_network_manager.hpp"
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
#include "network/protocols/connect_to_peer.hpp"
|
||||
#include "network/protocols/start_server.hpp"
|
||||
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/time.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
|
||||
ServerLobbyRoomProtocol::ServerLobbyRoomProtocol() : LobbyRoomProtocol(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ServerLobbyRoomProtocol::~ServerLobbyRoomProtocol()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ServerLobbyRoomProtocol::setup()
|
||||
{
|
||||
m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup
|
||||
m_next_id = 0;
|
||||
m_state = NONE;
|
||||
m_public_address.ip = 0;
|
||||
m_public_address.port = 0;
|
||||
Log::info("ServerLobbyRoomProtocol", "Starting the protocol.");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ServerLobbyRoomProtocol::notifyEvent(Event* event)
|
||||
{
|
||||
assert(m_setup); // assert that the setup exists
|
||||
if (event->type == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
assert(event->data.size()); // message not empty
|
||||
uint8_t message_type;
|
||||
message_type = event->data.getAndRemoveUInt8();
|
||||
Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type);
|
||||
if (message_type == 1) // player requesting connection
|
||||
{
|
||||
if (event->data.size() != 5 || event->data[0] != 4)
|
||||
{
|
||||
Log::warn("LobbyRoomProtocol", "A player is sending a badly formated message. Size is %d and first byte %d", event->data.size(), event->data[0]);
|
||||
return;
|
||||
}
|
||||
Log::verbose("LobbyRoomProtocol", "New player.");
|
||||
int player_id = 0;
|
||||
player_id = event->data.getUInt32(1);
|
||||
// can we add the player ?
|
||||
if (m_setup->getPlayerCount() < 16) // accept player
|
||||
{
|
||||
// add the player to the game setup
|
||||
while(m_setup->getProfile(m_next_id)!=NULL)
|
||||
m_next_id++;
|
||||
NetworkPlayerProfile profile;
|
||||
profile.race_id = m_next_id;
|
||||
profile.kart_name = "";
|
||||
profile.user_profile = new OnlineUser("Unnamed Player");
|
||||
m_setup->addPlayer(profile);
|
||||
// notify everybody that there is a new player
|
||||
NetworkString message;
|
||||
// new player (1) -- size of id -- id -- size of local id -- local id;
|
||||
message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id);
|
||||
m_listener->sendMessageExcept(this, event->peer, message);
|
||||
// send a message to the one that asked to connect
|
||||
NetworkString message_ack;
|
||||
// 0b10000001 (connection success) ;
|
||||
RandomGenerator token_generator;
|
||||
// use 4 random numbers because rand_max is probably 2^15-1.
|
||||
uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<16) & 0xff) +
|
||||
((token_generator.get(RAND_MAX)<<8) & 0xff) +
|
||||
((token_generator.get(RAND_MAX) & 0xff)));
|
||||
// connection success (129) -- size of token -- token
|
||||
message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id);
|
||||
m_listener->sendMessage(this, event->peer, message_ack);
|
||||
} // accept player
|
||||
else // refuse the connection with code 0 (too much players)
|
||||
{
|
||||
NetworkString message;
|
||||
message.ai8(0x80); // 128 means connection refused
|
||||
message.ai8(1); // 1 bytes for the error code
|
||||
message.ai8(0); // 0 = too much players
|
||||
// send only to the peer that made the request
|
||||
m_listener->sendMessage(this, event->peer, message);
|
||||
}
|
||||
}
|
||||
} // if (event->type == EVENT_TYPE_MESSAGE)
|
||||
else if (event->type == EVENT_TYPE_CONNECTED)
|
||||
{
|
||||
} // if (event->type == EVENT_TYPE_CONNECTED)
|
||||
else if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
{
|
||||
|
||||
} // if (event->type == EVENT_TYPE_DISCONNECTED)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ServerLobbyRoomProtocol::update()
|
||||
{
|
||||
switch (m_state)
|
||||
{
|
||||
case NONE:
|
||||
m_current_protocol_id = m_listener->requestStart(new GetPublicAddress(&m_public_address));
|
||||
m_state = GETTING_PUBLIC_ADDRESS;
|
||||
break;
|
||||
case GETTING_PUBLIC_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
NetworkManager::getInstance()->setPublicAddress(m_public_address);
|
||||
m_current_protocol_id = m_listener->requestStart(new StartServer());
|
||||
m_state = LAUNCHING_SERVER;
|
||||
Log::debug("ServerLobbyRoomProtocol", "Public address known.");
|
||||
}
|
||||
break;
|
||||
case LAUNCHING_SERVER:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
m_state = WORKING;
|
||||
Log::info("ServerLobbyRoomProtocol", "Server setup");
|
||||
}
|
||||
break;
|
||||
case WORKING:
|
||||
{
|
||||
// first poll every 5 seconds
|
||||
static double last_poll_time = 0;
|
||||
if (Time::getRealTime() > last_poll_time+10.0)
|
||||
{
|
||||
last_poll_time = Time::getRealTime();
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector->setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector->setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector->setParameter("address",addr.ip);
|
||||
connector->setParameter("port",addr.port);
|
||||
connector->setParameter("action","poll-connection-requests");
|
||||
|
||||
const XMLNode * result = connector->getXMLFromPage();
|
||||
std::string rec_success;
|
||||
if(result->get("success", &rec_success))
|
||||
{
|
||||
if(rec_success == "yes")
|
||||
{
|
||||
const XMLNode * users_xml = result->getNode("users");
|
||||
uint32_t id = 0;
|
||||
for (unsigned int i = 0; i < users_xml->getNumNodes(); i++)
|
||||
{
|
||||
users_xml->getNode(i)->get("id", &id);
|
||||
Log::debug("ServerLobbyRoomProtocol", "User with id %d wants to connect.", id);
|
||||
m_incoming_peers_ids.push_back(id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("ServerLobbyRoomProtocol", "Error while reading the list.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("ServerLobbyRoomProtocol", "Cannot retrieve the list.");
|
||||
}
|
||||
}
|
||||
|
||||
// now
|
||||
for (unsigned int i = 0; i < m_incoming_peers_ids.size(); i++)
|
||||
{
|
||||
m_listener->requestStart(new ConnectToPeer(m_incoming_peers_ids[i]));
|
||||
}
|
||||
m_incoming_peers_ids.clear();
|
||||
|
||||
break;
|
||||
}
|
||||
case DONE:
|
||||
m_listener->requestTerminate(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
33
src/network/protocols/server_lobby_room_protocol.hpp
Normal file
33
src/network/protocols/server_lobby_room_protocol.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef SERVER_LOBBY_ROOM_PROTOCOL_HPP
|
||||
#define SERVER_LOBBY_ROOM_PROTOCOL_HPP
|
||||
|
||||
#include "network/protocols/lobby_room_protocol.hpp"
|
||||
|
||||
class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
{
|
||||
public:
|
||||
ServerLobbyRoomProtocol();
|
||||
virtual ~ServerLobbyRoomProtocol();
|
||||
|
||||
virtual void notifyEvent(Event* event);
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
protected:
|
||||
uint8_t m_next_id; //!< Next id to assign to a peer.
|
||||
std::vector<TransportAddress> m_peers;
|
||||
std::vector<uint32_t> m_incoming_peers_ids;
|
||||
uint32_t m_current_protocol_id;
|
||||
TransportAddress m_public_address;
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
GETTING_PUBLIC_ADDRESS,
|
||||
LAUNCHING_SERVER,
|
||||
WORKING,
|
||||
DONE
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
#endif // SERVER_LOBBY_ROOM_PROTOCOL_HPP
|
@ -38,7 +38,6 @@ void* waitInput2(void* data)
|
||||
{
|
||||
std::string str = "";
|
||||
bool stop = false;
|
||||
int n = 0;
|
||||
while(!stop)
|
||||
{
|
||||
getline(std::cin, str);
|
||||
@ -95,7 +94,7 @@ void ServerNetworkManager::run()
|
||||
|
||||
void ServerNetworkManager::kickAllPlayers()
|
||||
{
|
||||
for (int i = 0; i < m_peers.size(); i++)
|
||||
for (unsigned int i = 0; i < m_peers.size(); i++)
|
||||
{
|
||||
m_peers[i]->disconnect();
|
||||
}
|
||||
|
@ -140,7 +140,8 @@ void STKHost::sendRawPacket(uint8_t* data, int length, TransportAddress dst)
|
||||
to.sin_addr.s_addr = htonl(dst.ip);
|
||||
|
||||
sendto(m_host->socket, (char*)data, length, 0,(sockaddr*)&to, to_len);
|
||||
Log::verbose("STKHost", "Raw packet sent to %u:%u\n", dst.ip, dst.port);
|
||||
Log::verbose("STKHost", "Raw packet sent to %i.%i.%i.%i:%u\n", ((dst.ip>>24)&0xff)
|
||||
, ((dst.ip>>16)&0xff), ((dst.ip>>8)&0xff), ((dst.ip>>0)&0xff), dst.port);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -42,7 +42,7 @@ class STKPeer
|
||||
|
||||
uint32_t getAddress() const;
|
||||
uint16_t getPort() const;
|
||||
uint32_t getClientServerToken() const;
|
||||
uint32_t getClientServerToken() const { return m_client_server_token; }
|
||||
bool isClientServerTokenSet() const { return m_token_set; }
|
||||
|
||||
bool operator==(const ENetPeer* peer) const;
|
||||
|
@ -29,3 +29,10 @@ OnlineUser::OnlineUser(const irr::core::stringw &username)
|
||||
m_name = username;
|
||||
} // OnlineUser
|
||||
|
||||
// ============================================================================
|
||||
OnlineUser::OnlineUser(const uint32_t& id)
|
||||
{
|
||||
m_id = id;
|
||||
} // OnlineUser
|
||||
|
||||
|
||||
|
@ -44,6 +44,7 @@ class OnlineUser
|
||||
* Constructor
|
||||
*/
|
||||
OnlineUser(const irr::core::stringw &username);
|
||||
OnlineUser(const uint32_t& id);
|
||||
|
||||
/** Returns the username. */
|
||||
irr::core::stringw getUserName() const { return m_name; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user