Started to refactor network code.
This commit is contained in:
parent
b8cd9cfb81
commit
350f434c37
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
29
src/main.cpp
29
src/main.cpp
@ -179,7 +179,7 @@
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/protocols/server_lobby_room_protocol.hpp"
|
||||
#include "network/client_network_manager.hpp"
|
||||
#include "network/server_network_manager.hpp"
|
||||
#include "network/server_console.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/protocols/server_lobby_room_protocol.hpp"
|
||||
#include "online/profile_manager.hpp"
|
||||
@ -782,9 +782,16 @@ int handleCmdLine()
|
||||
// Networking command lines
|
||||
if(CommandLine::has("--server") )
|
||||
{
|
||||
NetworkManager::getInstance<ServerNetworkManager>();
|
||||
Log::info("main", "Creating a server network manager.");
|
||||
} // -server
|
||||
STKHost::create(/*is_Server*/true);
|
||||
Log::info("main", "Creating a server.");
|
||||
}
|
||||
else
|
||||
{
|
||||
STKHost::create(/*is_server*/false);
|
||||
Log::info("main", "Creating a client.");
|
||||
}
|
||||
NetworkManager::getInstance<ClientNetworkManager>();
|
||||
NetworkManager::getInstance()->run();
|
||||
|
||||
if(CommandLine::has("--max-players", &n))
|
||||
UserConfigParams::m_server_max_players=n;
|
||||
@ -801,8 +808,8 @@ int handleCmdLine()
|
||||
// Race parameters
|
||||
if(CommandLine::has("--kartsize-debug"))
|
||||
{
|
||||
for(unsigned int i=0;
|
||||
i<kart_properties_manager->getNumberOfKarts(); i++)
|
||||
for(unsigned int i=0; i<kart_properties_manager->getNumberOfKarts();
|
||||
i++)
|
||||
{
|
||||
const KartProperties *km =
|
||||
kart_properties_manager->getKartById(i);
|
||||
@ -1343,17 +1350,13 @@ int main(int argc, char *argv[] )
|
||||
if(!handleCmdLine()) exit(0);
|
||||
|
||||
// load the network manager
|
||||
// If the server has been created (--server option), this will do nothing (just a warning):
|
||||
NetworkManager::getInstance<ClientNetworkManager>();
|
||||
if (NetworkManager::getInstance()->isServer())
|
||||
{
|
||||
ServerNetworkManager::getInstance()->setMaxPlayers(
|
||||
UserConfigParams::m_server_max_players);
|
||||
STKHost::setMaxPlayers(UserConfigParams::m_server_max_players);
|
||||
(new ServerLobbyRoomProtocol())->requestStart();
|
||||
}
|
||||
NetworkManager::getInstance()->run();
|
||||
if (NetworkManager::getInstance()->isServer())
|
||||
else // is client
|
||||
{
|
||||
ProtocolManager::getInstance()->requestStart(new ServerLobbyRoomProtocol());
|
||||
}
|
||||
|
||||
addons_manager->checkInstalledAddons();
|
||||
|
@ -134,9 +134,8 @@ void ClientNetworkManager::run()
|
||||
Log::error("ClientNetworkManager", "Could not initialize enet.\n");
|
||||
return;
|
||||
}
|
||||
m_localhost = new STKHost();
|
||||
m_localhost->setupClient(1, 2, 0, 0);
|
||||
m_localhost->startListening();
|
||||
STKHost::get()->setupClient(1, 2, 0, 0);
|
||||
STKHost::get()->startListening();
|
||||
|
||||
Log::info("ClientNetworkManager", "Host initialized.");
|
||||
|
||||
@ -170,9 +169,9 @@ void ClientNetworkManager::reset()
|
||||
NetworkManager::reset();
|
||||
|
||||
m_connected = false;
|
||||
m_localhost = new STKHost();
|
||||
m_localhost->setupClient(1, 2, 0, 0);
|
||||
m_localhost->startListening();
|
||||
STKHost::create(/*is_server*/false);
|
||||
STKHost::get()->setupClient(1, 2, 0, 0);
|
||||
STKHost::get()->startListening();
|
||||
|
||||
}
|
||||
|
||||
|
273
src/network/network.cpp
Executable file
273
src/network/network.cpp
Executable file
@ -0,0 +1,273 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013-2015 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "network/network.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#if defined(WIN32)
|
||||
# include "ws2tcpip.h"
|
||||
# define inet_ntop InetNtop
|
||||
#else
|
||||
# include <arpa/inet.h>
|
||||
# include <errno.h>
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
Synchronised<FILE*>Network::m_log_file = NULL;
|
||||
|
||||
// ============================================================================
|
||||
/** Constructor that just initialises this object (esp. opening the packet
|
||||
* log file), but it does not start a listener thread.
|
||||
* \param peer_count : The maximum number of peers.
|
||||
* \param channel_limit : The maximum number of channels per peer.
|
||||
* \param max_incoming_bandwidth : The maximum incoming bandwidth.
|
||||
* \param max_outgoing_bandwidth : The maximum outgoing bandwidth.
|
||||
*/
|
||||
Network::Network(int peer_count, int channel_limit,
|
||||
uint32_t max_incoming_bandwidth,
|
||||
uint32_t max_outgoing_bandwidth,
|
||||
ENetAddress* address)
|
||||
{
|
||||
m_host = enet_host_create(address, peer_count, channel_limit, 0, 0);
|
||||
if (!m_host)
|
||||
{
|
||||
Log::fatal("Network", "An error occurred while trying to create an "
|
||||
"ENet client host.");
|
||||
}
|
||||
} // Network
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Destructor. Stops the listening thread, closes the packet log file and
|
||||
* destroys the enet host.
|
||||
*/
|
||||
Network::~Network()
|
||||
{
|
||||
if (m_host)
|
||||
{
|
||||
enet_host_destroy(m_host);
|
||||
}
|
||||
} // ~Network
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
ENetPeer *Network::connectTo(const TransportAddress &address)
|
||||
{
|
||||
const ENetAddress enet_address = address.toEnetAddress();
|
||||
return enet_host_connect(m_host, &enet_address, 2, 0);
|
||||
} // connectTo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Sends a packet whithout ENet adding its headers.
|
||||
* This function is used in particular to achieve the STUN protocol.
|
||||
* \param data : Data to send.
|
||||
* \param length : Length of the sent data.
|
||||
* \param dst : Destination of the packet.
|
||||
*/
|
||||
void Network::sendRawPacket(uint8_t* data, int length,
|
||||
const TransportAddress& dst)
|
||||
{
|
||||
struct sockaddr_in to;
|
||||
int to_len = sizeof(to);
|
||||
memset(&to,0,to_len);
|
||||
|
||||
to.sin_family = AF_INET;
|
||||
to.sin_port = htons(dst.getPort());
|
||||
to.sin_addr.s_addr = htonl(dst.getIP());
|
||||
|
||||
sendto(m_host->socket, (char*)data, length, 0,(sockaddr*)&to, to_len);
|
||||
Log::verbose("Network", "Raw packet sent to %s",
|
||||
dst.toString().c_str());
|
||||
Network::logPacket(NetworkString(std::string((char*)(data), length)),
|
||||
false);
|
||||
} // sendRawPacket
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Receives a packet directly from the network interface.
|
||||
* Receive a packet whithout ENet processing it and returns the
|
||||
* sender's ip address and port in the TransportAddress structure.
|
||||
* \param sender : Stores the transport address of the sender of the
|
||||
* received packet.
|
||||
* \return A string containing the data of the received packet.
|
||||
*/
|
||||
uint8_t* Network::receiveRawPacket(TransportAddress* sender)
|
||||
{
|
||||
const int LEN = 2048;
|
||||
// max size needed normally (only used for stun)
|
||||
uint8_t* buffer = new uint8_t[LEN];
|
||||
memset(buffer, 0, LEN);
|
||||
|
||||
socklen_t from_len;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
from_len = sizeof(addr);
|
||||
int len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||
(struct sockaddr*)(&addr), &from_len );
|
||||
|
||||
int i = 0;
|
||||
// wait to receive the message because enet sockets are non-blocking
|
||||
while(len == -1) // nothing received
|
||||
{
|
||||
StkTime::sleep(1); // wait 1 millisecond between two checks
|
||||
i++;
|
||||
len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||
(struct sockaddr*)(&addr), &from_len );
|
||||
}
|
||||
if (len == SOCKET_ERROR)
|
||||
{
|
||||
Log::error("STKHost",
|
||||
"Problem with the socket. Please contact the dev team.");
|
||||
}
|
||||
// we received the data
|
||||
sender->setIP( ntohl((uint32_t)(addr.sin_addr.s_addr)) );
|
||||
sender->setPort( ntohs(addr.sin_port) );
|
||||
|
||||
if (addr.sin_family == AF_INET)
|
||||
{
|
||||
Log::info("STKHost", "IPv4 Address of the sender was %s",
|
||||
sender->toString().c_str());
|
||||
}
|
||||
return buffer;
|
||||
} // receiveRawPacket(TransportAddress* sender)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Receives a packet directly from the network interface and
|
||||
* filter its address.
|
||||
* Receive a packet whithout ENet processing it. Checks that the
|
||||
* sender of the packet is the one that corresponds to the sender
|
||||
* parameter. Does not check the port right now.
|
||||
* \param sender : Transport address of the original sender of the
|
||||
* wanted packet.
|
||||
* \param max_tries : Number of times we try to read data from the
|
||||
* socket. This is aproximately the time we wait in
|
||||
* milliseconds. -1 means eternal tries.
|
||||
* \return A string containing the data of the received packet
|
||||
* matching the sender's ip address.
|
||||
*/
|
||||
uint8_t* Network::receiveRawPacket(const TransportAddress& sender,
|
||||
int max_tries)
|
||||
{
|
||||
const int LEN = 2048;
|
||||
uint8_t* buffer = new uint8_t[LEN];
|
||||
memset(buffer, 0, LEN);
|
||||
|
||||
socklen_t from_len;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
from_len = sizeof(addr);
|
||||
int len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||
(struct sockaddr*)(&addr), &from_len );
|
||||
|
||||
int count = 0;
|
||||
// wait to receive the message because enet sockets are non-blocking
|
||||
while(len < 0 || addr.sin_addr.s_addr == sender.getIP())
|
||||
{
|
||||
count++;
|
||||
if (len>=0)
|
||||
{
|
||||
Log::info("STKHost", "Message received but the ip address didn't "
|
||||
"match the expected one.");
|
||||
}
|
||||
len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||
(struct sockaddr*)(&addr), &from_len);
|
||||
StkTime::sleep(1); // wait 1 millisecond between two checks
|
||||
if (count >= max_tries && max_tries != -1)
|
||||
{
|
||||
TransportAddress a(m_host->address);
|
||||
Log::verbose("STKHost", "No answer from the server on %s",
|
||||
a.toString().c_str());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (addr.sin_family == AF_INET)
|
||||
{
|
||||
TransportAddress a(ntohl(addr.sin_addr.s_addr));
|
||||
Log::info("STKHost", "IPv4 Address of the sender was %s",
|
||||
a.toString(false).c_str());
|
||||
}
|
||||
Network::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
|
||||
return buffer;
|
||||
} // receiveRawPacket(const TransportAddress& sender, int max_tries)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Broadcasts a packet to all peers.
|
||||
* \param data : Data to send.
|
||||
*/
|
||||
void Network::broadcastPacket(const NetworkString& data, bool reliable)
|
||||
{
|
||||
ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1,
|
||||
reliable ? ENET_PACKET_FLAG_RELIABLE
|
||||
: ENET_PACKET_FLAG_UNSEQUENCED);
|
||||
enet_host_broadcast(m_host, 0, packet);
|
||||
} // broadcastPacket
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Network::openLog()
|
||||
{
|
||||
m_log_file.setAtomic(NULL);
|
||||
if (UserConfigParams::m_packets_log_filename.toString() != "")
|
||||
{
|
||||
std::string s = file_manager
|
||||
->getUserConfigFile(UserConfigParams::m_packets_log_filename);
|
||||
m_log_file.setAtomic(fopen(s.c_str(), "w+"));
|
||||
}
|
||||
if (!m_log_file.getData())
|
||||
Log::warn("STKHost", "Network packets won't be logged: no file.");
|
||||
} // openLog
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Log packets into a file
|
||||
* \param ns : The data in the packet
|
||||
* \param incoming : True if the packet comes from a peer.
|
||||
* False if it's sent to a peer.
|
||||
*/
|
||||
void Network::logPacket(const NetworkString &ns, bool incoming)
|
||||
{
|
||||
if (m_log_file.getData() == NULL) // read only access, no need to lock
|
||||
return;
|
||||
|
||||
const char *arrow = incoming ? "<--" : "-->";
|
||||
|
||||
m_log_file.lock();
|
||||
fprintf(m_log_file.getData(), "[%d\t] %s ",
|
||||
(int)(StkTime::getRealTime()), arrow);
|
||||
|
||||
for (int i = 0; i < ns.size(); i++)
|
||||
{
|
||||
fprintf(m_log_file.getData(), "%d.", ns[i]);
|
||||
}
|
||||
fprintf(m_log_file.getData(), "\n");
|
||||
m_log_file.unlock();
|
||||
} // logPacket
|
||||
// ----------------------------------------------------------------------------
|
||||
void Network::closeLog()
|
||||
{
|
||||
if (m_log_file.getData())
|
||||
{
|
||||
m_log_file.lock();
|
||||
fclose(m_log_file.getData());
|
||||
Log::warn("STKHost", "Packet logging file has been closed.");
|
||||
m_log_file.getData() = NULL;
|
||||
m_log_file.unlock();
|
||||
}
|
||||
} // closeLog
|
72
src/network/network.hpp
Normal file
72
src/network/network.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013-2015 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
/*! \file network.hpp
|
||||
* \brief Defines an interface to use network low-level functions easily.
|
||||
*/
|
||||
#ifndef HEADER_NETWORK_HPP
|
||||
#define HEADER_NETWORK_HPP
|
||||
|
||||
#include "network/types.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
|
||||
// enet.h includes win32.h, which without lean_and_mean includes
|
||||
// winspool.h, which defines MAX_PRIORITY as a macro, which then
|
||||
// results in request_manager.hpp not being compilable.
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <enet/enet.h>
|
||||
|
||||
class NetworkString;
|
||||
|
||||
/** \class EnetHost
|
||||
* A small wrapper around enet to allow sending and receiving
|
||||
* packages.
|
||||
*/
|
||||
class Network
|
||||
{
|
||||
private:
|
||||
/** ENet host interfacing sockets. */
|
||||
ENetHost* m_host;
|
||||
|
||||
/** Where to log packets. If NULL for FILE* logging is disabled. */
|
||||
static Synchronised<FILE*> m_log_file;
|
||||
|
||||
public:
|
||||
Network(int peer_count, int channel_limit,
|
||||
uint32_t max_incoming_bandwidth,
|
||||
uint32_t max_outgoing_bandwidth,
|
||||
ENetAddress* address = NULL);
|
||||
virtual ~Network();
|
||||
|
||||
static void openLog();
|
||||
static void logPacket(const NetworkString &ns, bool incoming);
|
||||
static void closeLog();
|
||||
ENetPeer *connectTo(const TransportAddress &address);
|
||||
void sendRawPacket(uint8_t* data, int length,
|
||||
const TransportAddress& dst);
|
||||
uint8_t* receiveRawPacket(TransportAddress* sender);
|
||||
uint8_t* receiveRawPacket(const TransportAddress& sender,
|
||||
int max_tries = -1);
|
||||
void broadcastPacket(const NetworkString& data,
|
||||
bool reliable = true);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a pointer to the ENet host object. */
|
||||
ENetHost* getENetHost() { return m_host; }
|
||||
}; // class Network
|
||||
|
||||
#endif // HEADER_ENET_SOCKET_HPP
|
@ -33,7 +33,6 @@ NetworkManager::NetworkManager()
|
||||
m_public_address.lock();
|
||||
m_public_address.getData().clear();
|
||||
m_public_address.unlock();
|
||||
m_localhost = NULL;
|
||||
m_game_setup = NULL;
|
||||
} // NetworkManager
|
||||
|
||||
@ -43,8 +42,7 @@ NetworkManager::~NetworkManager()
|
||||
{
|
||||
ProtocolManager::kill();
|
||||
|
||||
if (m_localhost)
|
||||
delete m_localhost;
|
||||
STKHost::destroy();
|
||||
while(!m_peers.empty())
|
||||
{
|
||||
delete m_peers.back();
|
||||
@ -57,8 +55,6 @@ NetworkManager::~NetworkManager()
|
||||
*/
|
||||
void NetworkManager::run()
|
||||
{
|
||||
// create the protocol manager
|
||||
ProtocolManager::getInstance<ProtocolManager>();
|
||||
} // run
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -67,9 +63,7 @@ void NetworkManager::run()
|
||||
*/
|
||||
void NetworkManager::reset()
|
||||
{
|
||||
if (m_localhost)
|
||||
delete m_localhost;
|
||||
m_localhost = NULL;
|
||||
STKHost::destroy();
|
||||
while(!m_peers.empty())
|
||||
{
|
||||
delete m_peers.back();
|
||||
@ -84,7 +78,7 @@ void NetworkManager::reset()
|
||||
*/
|
||||
void NetworkManager::abort()
|
||||
{
|
||||
m_localhost->stopListening();
|
||||
STKHost::get()->stopListening();
|
||||
// FIXME: Why a reset here? This creates a new stk_host, which will open
|
||||
// a new packet_log file (and therefore delete the previous file)???
|
||||
// reset();
|
||||
@ -101,7 +95,7 @@ bool NetworkManager::connect(const TransportAddress& address)
|
||||
if (peerExists(address))
|
||||
return isConnectedTo(address);
|
||||
|
||||
return STKPeer::connectToHost(m_localhost, address, 2, 0);
|
||||
return STKPeer::connectToHost(STKHost::get(), address, 2, 0);
|
||||
} // connect
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -51,10 +51,6 @@ protected:
|
||||
NetworkManager();
|
||||
virtual ~NetworkManager();
|
||||
|
||||
/** Pointer to the one stk host instance, which is used to do all
|
||||
* network communication. */
|
||||
STKHost* m_localhost;
|
||||
|
||||
/** The list of peers connected to this instance. */
|
||||
std::vector<STKPeer*> m_peers;
|
||||
|
||||
@ -99,19 +95,17 @@ public:
|
||||
* already exists. */
|
||||
virtual bool peerExists(const TransportAddress& peer)
|
||||
{
|
||||
return m_localhost->peerExists(peer);
|
||||
return STKHost::get()->peerExists(peer);
|
||||
} // peerExists
|
||||
// --------------------------------------------------------------------
|
||||
virtual bool isConnectedTo(const TransportAddress& peer)
|
||||
{
|
||||
return m_localhost->isConnectedTo(peer);
|
||||
return STKHost::get()->isConnectedTo(peer);
|
||||
} // isConnectedTo
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
inline bool isClient() { return !isServer(); }
|
||||
// --------------------------------------------------------------------
|
||||
STKHost* getHost() { return m_localhost; }
|
||||
// --------------------------------------------------------------------
|
||||
std::vector<STKPeer*> getPeers() { return m_peers; }
|
||||
// --------------------------------------------------------------------
|
||||
unsigned int getPeerCount() { return (int)m_peers.size(); }
|
||||
|
@ -22,39 +22,30 @@
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
|
||||
/** \brief Constructor
|
||||
* Sets the basic protocol parameters, as the callback object and the
|
||||
* protocol type.
|
||||
* \param callback_object The callback object that will be used by the
|
||||
* protocol. Protocols that do not use callback objects must set
|
||||
* it to NULL.
|
||||
* \param type The type of the protocol.
|
||||
*/
|
||||
Protocol::Protocol(CallbackObject* callback_object, ProtocolType type)
|
||||
{
|
||||
m_callback_object = callback_object;
|
||||
m_type = type;
|
||||
}
|
||||
m_type = type;
|
||||
m_state = PROTOCOL_STATE_INITIALISING;
|
||||
m_id = 0;
|
||||
} // Protocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Destructor.
|
||||
*/
|
||||
Protocol::~Protocol()
|
||||
{
|
||||
}
|
||||
|
||||
void Protocol::pause()
|
||||
{
|
||||
m_listener->requestPause(this);
|
||||
}
|
||||
void Protocol::unpause()
|
||||
{
|
||||
m_listener->requestUnpause(this);
|
||||
}
|
||||
|
||||
void Protocol::kill()
|
||||
{
|
||||
}
|
||||
|
||||
void Protocol::setListener(ProtocolManager* listener)
|
||||
{
|
||||
m_listener = listener;
|
||||
}
|
||||
|
||||
ProtocolType Protocol::getProtocolType()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
} // ~Protocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool Protocol::checkDataSizeAndToken(Event* event, int minimum_size)
|
||||
{
|
||||
const NetworkString &data = event->data();
|
||||
@ -74,8 +65,9 @@ bool Protocol::checkDataSizeAndToken(Event* event, int minimum_size)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // checkDataSizeAndToken
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool Protocol::isByteCorrect(Event* event, int byte_nb, int value)
|
||||
{
|
||||
const NetworkString &data = event->data();
|
||||
@ -86,15 +78,46 @@ bool Protocol::isByteCorrect(Event* event, int byte_nb, int value)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // isByteCorrect
|
||||
|
||||
void Protocol::sendMessageToPeersChangingToken(NetworkString prefix, NetworkString message)
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Starts a request in the protocol manager to start this protocol.
|
||||
*/
|
||||
void Protocol::requestStart()
|
||||
{
|
||||
ProtocolManager::getInstance()->requestStart(this);
|
||||
} // requestStart
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Submits a request to the ProtocolManager to terminate this protocol.
|
||||
*/
|
||||
void Protocol::requestTerminate()
|
||||
{
|
||||
ProtocolManager::getInstance()->requestTerminate(this);
|
||||
} // requestTerminate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Protocol::sendMessageToPeersChangingToken(NetworkString prefix,
|
||||
NetworkString message)
|
||||
{
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
{
|
||||
prefix.ai8(4).ai32(peers[i]->getClientServerToken());
|
||||
prefix += message;
|
||||
m_listener->sendMessage(this, peers[i], prefix);
|
||||
ProtocolManager::getInstance()->sendMessage(this, peers[i], prefix);
|
||||
}
|
||||
}
|
||||
} // sendMessageToPeersChangingToken
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Protocol::sendMessage(const NetworkString& message, bool reliable)
|
||||
{
|
||||
ProtocolManager::getInstance()->sendMessage(this, message, reliable);
|
||||
} // sendMessage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Protocol::sendMessage(STKPeer* peer, const NetworkString& message,
|
||||
bool reliable)
|
||||
{
|
||||
ProtocolManager::getInstance()->sendMessage(this, peer, message, reliable);
|
||||
} // sendMessage
|
||||
|
@ -25,105 +25,134 @@
|
||||
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/types.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
class Event;
|
||||
class ProtocolManager;
|
||||
class STKPeer;
|
||||
|
||||
|
||||
/** \enum ProtocolType
|
||||
* \brief The types that protocols can have. This is used to select which protocol receives which event.
|
||||
* \ingroup network
|
||||
*/
|
||||
* \brief The types that protocols can have. This is used to select which
|
||||
* protocol receives which event.
|
||||
* \ingroup network
|
||||
*/
|
||||
enum ProtocolType
|
||||
{
|
||||
PROTOCOL_NONE = 0, //!< No protocol type assigned.
|
||||
PROTOCOL_CONNECTION = 1, //!< Protocol that deals with client-server connection.
|
||||
PROTOCOL_LOBBY_ROOM = 2, //!< Protocol that is used during the lobby room phase.
|
||||
PROTOCOL_START_GAME = 3, //!< Protocol used when starting the game.
|
||||
PROTOCOL_SYNCHRONIZATION = 4,//!<Protocol used to synchronize clocks.
|
||||
PROTOCOL_KART_UPDATE = 5, //!< Protocol to update karts position, rotation etc...
|
||||
PROTOCOL_GAME_EVENTS = 6, //!< Protocol to communicate the game events.
|
||||
PROTOCOL_CONTROLLER_EVENTS = 7,//!< Protocol to transfer controller modifications
|
||||
PROTOCOL_SILENT = 0xffff //!< Used for protocols that do not subscribe to any network event.
|
||||
};
|
||||
PROTOCOL_NONE = 0, //!< No protocol type assigned.
|
||||
PROTOCOL_CONNECTION = 1, //!< Protocol that deals with client-server connection.
|
||||
PROTOCOL_LOBBY_ROOM = 2, //!< Protocol that is used during the lobby room phase.
|
||||
PROTOCOL_START_GAME = 3, //!< Protocol used when starting the game.
|
||||
PROTOCOL_SYNCHRONIZATION = 4, //!<Protocol used to synchronize clocks.
|
||||
PROTOCOL_KART_UPDATE = 5, //!< Protocol to update karts position, rotation etc...
|
||||
PROTOCOL_GAME_EVENTS = 6, //!< Protocol to communicate the game events.
|
||||
PROTOCOL_CONTROLLER_EVENTS = 7, //!< Protocol to transfer controller modifications
|
||||
PROTOCOL_SILENT = 0xffff //!< Used for protocols that do not subscribe to any network event.
|
||||
}; // ProtocolType
|
||||
|
||||
/** \class Protocol
|
||||
* \brief Abstract class used to define the global protocol functions.
|
||||
* A protocol is an entity that is started at a point, and that is updated by a thread.
|
||||
* A protocol can be terminated by an other class, or it can terminate itself if has fulfilled its role.
|
||||
* This class must be inherited to make any network job.
|
||||
* \ingroup network
|
||||
*/
|
||||
class Protocol
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \enum ProtocolState
|
||||
* \brief Defines the three states that a protocol can have.
|
||||
*/
|
||||
enum ProtocolState
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* \brief Constructor
|
||||
*
|
||||
* Sets the basic protocol parameters, as the callback object and the protocol type.
|
||||
*
|
||||
* \param callback_object The callback object that will be used by the protocol. Protocols that do not use callback objects must set it to NULL.
|
||||
* \param type The type of the protocol.
|
||||
*/
|
||||
Protocol(CallbackObject* callback_object, ProtocolType type);
|
||||
/*! \brief Destructor
|
||||
*/
|
||||
virtual ~Protocol();
|
||||
PROTOCOL_STATE_INITIALISING, //!< The protocol is waiting to be started
|
||||
PROTOCOL_STATE_RUNNING, //!< The protocol is being updated everytime.
|
||||
PROTOCOL_STATE_PAUSED, //!< The protocol is paused.
|
||||
PROTOCOL_STATE_TERMINATED //!< The protocol is terminated/does not exist.
|
||||
}; // ProtocolState
|
||||
|
||||
/*! \brief Notify a protocol matching the Event type of that event.
|
||||
* \param event : Pointer to the event.
|
||||
* \return True if the event has been treated, false elseway
|
||||
*/
|
||||
virtual bool notifyEvent(Event* event) { return false; }
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \class Protocol
|
||||
* \brief Abstract class used to define the global protocol functions.
|
||||
* A protocol is an entity that is started at a point, and that is updated
|
||||
* by a thread. A protocol can be terminated by an other class, or it can
|
||||
* terminate itself if has fulfilled its role. This class must be inherited
|
||||
* to make any network job.
|
||||
* \ingroup network
|
||||
*/
|
||||
class Protocol : public NoCopy
|
||||
{
|
||||
protected:
|
||||
/** The type of the protocol. */
|
||||
ProtocolType m_type;
|
||||
|
||||
/*! \brief Notify a protocol matching the Event type of that event.
|
||||
* This update is done asynchronously :
|
||||
* \param event : Pointer to the event.
|
||||
* \return True if the event has been treated, false elseway
|
||||
*/
|
||||
virtual bool notifyEventAsynchronous(Event* event) { return false; }
|
||||
/** The callback object, if needed. */
|
||||
CallbackObject* m_callback_object;
|
||||
|
||||
/*! \brief Set the protocol listener.
|
||||
* \param listener : Pointer to the listener.
|
||||
*/
|
||||
void setListener(ProtocolManager* listener);
|
||||
/** The state this protocol is in (e.g. running, paused, ...). */
|
||||
ProtocolState m_state;
|
||||
|
||||
/*! \brief Called when the protocol is going to start. Must be re-defined by subclasses.
|
||||
*/
|
||||
virtual void setup() = 0;
|
||||
/*! \brief Called when the protocol is paused (by an other entity or by itself).
|
||||
* This function must be called by the subclasse's pause function if re-defined.
|
||||
*/
|
||||
virtual void pause();
|
||||
/*! \brief Called when the protocol is unpaused.
|
||||
* This function must be called by the subclasse's unpause function if re-defined.
|
||||
*/
|
||||
virtual void unpause();
|
||||
/*! \brief Called by the protocol listener, synchronously with the main loop. Must be re-defined.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
/*! \brief Called by the protocol listener as often as possible. Must be re-defined.
|
||||
*/
|
||||
virtual void asynchronousUpdate() = 0;
|
||||
/*! \brief Called when the protocol is to be killed.
|
||||
*/
|
||||
virtual void kill();
|
||||
/** The unique id of the protocol. */
|
||||
uint32_t m_id;
|
||||
|
||||
/*! \brief Method to get a protocol's type.
|
||||
* \return The protocol type.
|
||||
*/
|
||||
ProtocolType getProtocolType();
|
||||
public:
|
||||
|
||||
/// functions to check incoming data easily
|
||||
bool checkDataSizeAndToken(Event* event, int minimum_size);
|
||||
bool isByteCorrect(Event* event, int byte_nb, int value);
|
||||
void sendMessageToPeersChangingToken(NetworkString prefix, NetworkString message);
|
||||
Protocol(CallbackObject* callback_object, ProtocolType type);
|
||||
virtual ~Protocol();
|
||||
/** \brief Called when the protocol is going to start. Must be re-defined
|
||||
* by subclasses. */
|
||||
virtual void setup() = 0;
|
||||
|
||||
/** \brief Called by the protocol listener, synchronously with the main
|
||||
* loop. Must be re-defined.*/
|
||||
virtual void update() = 0;
|
||||
|
||||
/** \brief Called by the protocol listener as often as possible.
|
||||
* Must be re-defined. */
|
||||
virtual void asynchronousUpdate() = 0;
|
||||
|
||||
/// functions to check incoming data easily
|
||||
bool checkDataSizeAndToken(Event* event, int minimum_size);
|
||||
bool isByteCorrect(Event* event, int byte_nb, int value);
|
||||
void sendMessageToPeersChangingToken(NetworkString prefix,
|
||||
NetworkString message);
|
||||
void sendMessage(const NetworkString& message,
|
||||
bool reliable = true);
|
||||
void sendMessage(STKPeer* peer, const NetworkString& message,
|
||||
bool reliable = true);
|
||||
void requestStart();
|
||||
void requestTerminate();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current protocol state. */
|
||||
ProtocolState getState() const { return m_state; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the current protocol state. */
|
||||
void setState(ProtocolState s) { m_state = s; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the unique protocol ID. */
|
||||
uint32_t getId() const { return m_id; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the unique protocol id. */
|
||||
void setId(uint32_t id) { m_id = id; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Notify a protocol matching the Event type of that event.
|
||||
* \param event : Pointer to the event.
|
||||
* \return True if the event has been treated, false otherwise. */
|
||||
virtual bool notifyEvent(Event* event) { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Notify a protocol matching the Event type of that event.
|
||||
* This update is done asynchronously :
|
||||
* \param event : Pointer to the event.
|
||||
* \return True if the event has been treated, false otherwise */
|
||||
virtual bool notifyEventAsynchronous(Event* event) { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Called when the protocol is paused (by an other entity or by
|
||||
* itself). */
|
||||
virtual void pause() { }
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Called when the protocol is used.
|
||||
*/
|
||||
virtual void unpause() { }
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Called when the protocol is to be killed. */
|
||||
virtual void kill() {}
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Method to get a protocol's type.
|
||||
* \return The protocol type. */
|
||||
ProtocolType getProtocolType() const { return m_type; }
|
||||
|
||||
|
||||
protected:
|
||||
ProtocolManager* m_listener; //!< The protocol listener
|
||||
ProtocolType m_type; //!< The type of the protocol
|
||||
CallbackObject* m_callback_object; //!< The callback object, if needed
|
||||
};
|
||||
}; // class Protocol
|
||||
|
||||
#endif // PROTOCOL_HPP
|
||||
|
@ -79,7 +79,7 @@ void ProtocolManager::abort()
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
pthread_mutex_lock(&m_id_mutex);
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size() ; i++)
|
||||
delete m_protocols.getData()[i].m_protocol;
|
||||
delete m_protocols.getData()[i];
|
||||
for (unsigned int i = 0; i < m_events_to_process.getData().size() ; i++)
|
||||
delete m_events_to_process.getData()[i].m_event;
|
||||
m_protocols.getData().clear();
|
||||
@ -131,12 +131,12 @@ void ProtocolManager::propagateEvent(Event* event)
|
||||
m_protocols.lock();
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size() ; i++)
|
||||
{
|
||||
const ProtocolInfo &pi = m_protocols.getData()[i];
|
||||
const Protocol *p = m_protocols.getData()[i];
|
||||
// Pass data to protocols even when paused
|
||||
if (pi.m_protocol->getProtocolType() == searched_protocol ||
|
||||
if (p->getProtocolType() == searched_protocol ||
|
||||
event->getType() == EVENT_TYPE_DISCONNECTED)
|
||||
{
|
||||
protocols_ids.push_back(pi.m_id);
|
||||
protocols_ids.push_back(p->getId());
|
||||
}
|
||||
} // for i in m_protocols
|
||||
m_protocols.unlock();
|
||||
@ -209,18 +209,16 @@ void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer,
|
||||
*/
|
||||
uint32_t ProtocolManager::requestStart(Protocol* protocol)
|
||||
{
|
||||
// assign a unique id to the protocol.
|
||||
protocol->setId(getNextProtocolId());
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_protocol_info.m_state = PROTOCOL_STATE_INITIALISING;
|
||||
assignProtocolId(&req.m_protocol_info); // assign a unique id to the protocol.
|
||||
req.m_type = PROTOCOL_REQUEST_START;
|
||||
ProtocolRequest req(PROTOCOL_REQUEST_START, protocol);
|
||||
// add it to the request stack
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
|
||||
return req.m_protocol_info.m_id;
|
||||
return req.getProtocol()->getId();
|
||||
} // requestStart
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -234,9 +232,7 @@ void ProtocolManager::requestStop(Protocol* protocol)
|
||||
if (!protocol)
|
||||
return;
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_type = PROTOCOL_REQUEST_STOP;
|
||||
ProtocolRequest req(PROTOCOL_REQUEST_STOP, protocol);
|
||||
// add it to the request stack
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
@ -254,9 +250,7 @@ void ProtocolManager::requestPause(Protocol* protocol)
|
||||
if (!protocol)
|
||||
return;
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_type = PROTOCOL_REQUEST_PAUSE;
|
||||
ProtocolRequest req(PROTOCOL_REQUEST_PAUSE, protocol);
|
||||
// add it to the request stack
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
@ -274,9 +268,7 @@ void ProtocolManager::requestUnpause(Protocol* protocol)
|
||||
if (!protocol)
|
||||
return;
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_type = PROTOCOL_REQUEST_UNPAUSE;
|
||||
ProtocolRequest req(PROTOCOL_REQUEST_UNPAUSE, protocol);;
|
||||
// add it to the request stack
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
@ -294,15 +286,13 @@ void ProtocolManager::requestTerminate(Protocol* protocol)
|
||||
if (!protocol)
|
||||
return;
|
||||
// create the request
|
||||
ProtocolRequest req;
|
||||
req.m_protocol_info.m_protocol = protocol;
|
||||
req.m_type = PROTOCOL_REQUEST_TERMINATE;
|
||||
ProtocolRequest req(PROTOCOL_REQUEST_TERMINATE, protocol);
|
||||
// add it to the request stack
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
// check that the request does not already exist :
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
if (m_requests[i].m_protocol_info.m_protocol == protocol)
|
||||
if (m_requests[i].m_protocol == protocol)
|
||||
{
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
return;
|
||||
@ -317,75 +307,88 @@ void ProtocolManager::requestTerminate(Protocol* protocol)
|
||||
* Add the protocol info to the m_protocols vector.
|
||||
* \param protocol : ProtocolInfo to start.
|
||||
*/
|
||||
void ProtocolManager::startProtocol(ProtocolInfo &protocol)
|
||||
void ProtocolManager::startProtocol(Protocol *protocol)
|
||||
{
|
||||
assert(protocol.m_state == PROTOCOL_STATE_INITIALISING);
|
||||
// assert(protocol_info.m_state == PROTOCOL_STATE_INITIALISING);
|
||||
// add the protocol to the protocol vector so that it's updated
|
||||
m_protocols.lock();
|
||||
pthread_mutex_lock(&m_asynchronous_protocols_mutex);
|
||||
Log::info("ProtocolManager",
|
||||
"A %s protocol with id=%u has been started. There are %ld protocols running.",
|
||||
typeid(*protocol.m_protocol).name(), protocol.m_id,
|
||||
typeid(protocol).name(), protocol->getId(),
|
||||
m_protocols.getData().size()+1);
|
||||
m_protocols.getData().push_back(protocol);
|
||||
// setup the protocol and notify it that it's started
|
||||
protocol.m_protocol->setListener(this);
|
||||
protocol.m_protocol->setup();
|
||||
protocol.m_state = PROTOCOL_STATE_RUNNING;
|
||||
protocol->setup();
|
||||
protocol->setState(PROTOCOL_STATE_RUNNING);
|
||||
m_protocols.unlock();
|
||||
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
|
||||
} // startProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::stopProtocol(ProtocolInfo protocol)
|
||||
void ProtocolManager::stopProtocol(Protocol *protocol)
|
||||
{
|
||||
} // stopProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::pauseProtocol(ProtocolInfo protocol)
|
||||
void ProtocolManager::pauseProtocol(Protocol *protocol)
|
||||
{
|
||||
assert(protocol->getState() == PROTOCOL_STATE_RUNNING);
|
||||
protocol->setState(PROTOCOL_STATE_PAUSED);
|
||||
|
||||
return;
|
||||
|
||||
// FIXME ... why so complicated???
|
||||
#ifdef XX
|
||||
// FIXME Does this need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
ProtocolInfo &pi = m_protocols.getData()[i];
|
||||
if (pi.m_protocol == protocol.m_protocol &&
|
||||
pi.m_state == PROTOCOL_STATE_RUNNING)
|
||||
//ProtocolInfo *pi = m_protocols.getData()[i];
|
||||
if (pi->m_protocol == protocol.m_protocol &&
|
||||
pi->m_state == PROTOCOL_STATE_RUNNING)
|
||||
{
|
||||
pi.m_state = PROTOCOL_STATE_PAUSED;
|
||||
pi.m_protocol->pause();
|
||||
pi->m_state = PROTOCOL_STATE_PAUSED;
|
||||
pi->m_protocol->pause();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // pauseProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::unpauseProtocol(ProtocolInfo protocol)
|
||||
void ProtocolManager::unpauseProtocol(Protocol *protocol)
|
||||
{
|
||||
protocol->setState(PROTOCOL_STATE_RUNNING);
|
||||
protocol->unpause();
|
||||
//FIXME: why call protocol->unpause() (which would queue a new request and
|
||||
// then calls this function again) ... and why so complicated??
|
||||
#ifdef XX
|
||||
// FIXME Does this need to be locked??
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
ProtocolInfo &p = m_protocols.getData()[i];
|
||||
if (p.m_protocol == protocol.m_protocol &&
|
||||
p.m_state == PROTOCOL_STATE_PAUSED)
|
||||
ProtocolInfo *p = m_protocols.getData()[i];
|
||||
if (p->m_protocol == protocol.m_protocol &&
|
||||
p->m_state == PROTOCOL_STATE_PAUSED)
|
||||
{
|
||||
p.m_state = PROTOCOL_STATE_RUNNING;
|
||||
p.m_protocol->unpause();
|
||||
p->m_state = PROTOCOL_STATE_RUNNING;
|
||||
p->m_protocol->unpause();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // unpauseProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::protocolTerminated(ProtocolInfo protocol)
|
||||
void ProtocolManager::protocolTerminated(Protocol *protocol)
|
||||
{
|
||||
// Be sure that noone accesses the protocols vector while we erase a protocol
|
||||
m_protocols.lock();
|
||||
pthread_mutex_lock(&m_asynchronous_protocols_mutex);
|
||||
int offset = 0;
|
||||
std::string protocol_type = typeid(*protocol.m_protocol).name();
|
||||
std::string protocol_type = typeid(protocol).name();
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i-offset].m_protocol == protocol.m_protocol)
|
||||
if (m_protocols.getData()[i-offset] == protocol)
|
||||
{
|
||||
delete m_protocols.getData()[i].m_protocol;
|
||||
delete protocol;
|
||||
m_protocols.getData().erase(m_protocols.getData().begin()+(i-offset),
|
||||
m_protocols.getData().begin()+(i-offset)+1);
|
||||
offset++;
|
||||
@ -407,14 +410,14 @@ bool ProtocolManager::sendEvent(EventProcessingInfo* event, bool synchronous)
|
||||
int index = 0;
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (event->m_protocols_ids[index] == m_protocols.getData()[i].m_id)
|
||||
if (event->m_protocols_ids[index] == m_protocols.getData()[i]->getId())
|
||||
{
|
||||
bool result = false;
|
||||
if (synchronous)
|
||||
result = m_protocols.getData()[i].m_protocol
|
||||
result = m_protocols.getData()[i]
|
||||
->notifyEvent(event->m_event);
|
||||
else
|
||||
result = m_protocols.getData()[i].m_protocol
|
||||
result = m_protocols.getData()[i]
|
||||
->notifyEventAsynchronous(event->m_event);
|
||||
if (result)
|
||||
event->m_protocols_ids.pop_back();
|
||||
@ -465,8 +468,8 @@ void ProtocolManager::update()
|
||||
m_protocols.lock();
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].m_state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i].m_protocol->update();
|
||||
if (m_protocols.getData()[i]->getState() == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i]->update();
|
||||
}
|
||||
m_protocols.unlock();
|
||||
} // update
|
||||
@ -504,8 +507,8 @@ void ProtocolManager::asynchronousUpdate()
|
||||
// FIXME: does m_protocols need to be locked???
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].m_state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i].m_protocol->asynchronousUpdate();
|
||||
if (m_protocols.getData()[i]->getState() == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i]->asynchronousUpdate();
|
||||
}
|
||||
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
|
||||
|
||||
@ -514,22 +517,22 @@ void ProtocolManager::asynchronousUpdate()
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
switch (m_requests[i].m_type)
|
||||
switch (m_requests[i].getType())
|
||||
{
|
||||
case PROTOCOL_REQUEST_START:
|
||||
startProtocol(m_requests[i].m_protocol_info);
|
||||
startProtocol(m_requests[i].getProtocol());
|
||||
break;
|
||||
case PROTOCOL_REQUEST_STOP:
|
||||
stopProtocol(m_requests[i].m_protocol_info);
|
||||
stopProtocol(m_requests[i].getProtocol());
|
||||
break;
|
||||
case PROTOCOL_REQUEST_PAUSE:
|
||||
pauseProtocol(m_requests[i].m_protocol_info);
|
||||
pauseProtocol(m_requests[i].getProtocol());
|
||||
break;
|
||||
case PROTOCOL_REQUEST_UNPAUSE:
|
||||
unpauseProtocol(m_requests[i].m_protocol_info);
|
||||
unpauseProtocol(m_requests[i].getProtocol());
|
||||
break;
|
||||
case PROTOCOL_REQUEST_TERMINATE:
|
||||
protocolTerminated(m_requests[i].m_protocol_info);
|
||||
protocolTerminated(m_requests[i].getProtocol());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -548,14 +551,14 @@ ProtocolState ProtocolManager::getProtocolState(uint32_t id)
|
||||
// a locked section anyway
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].m_id == id) // we know a protocol with that id
|
||||
return m_protocols.getData()[i].m_state;
|
||||
if (m_protocols.getData()[i]->getId() == id) // we know a protocol with that id
|
||||
return m_protocols.getData()[i]->getState();
|
||||
}
|
||||
// the protocol isn't running right now
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
// the protocol is going to be started
|
||||
if (m_requests[i].m_protocol_info.m_id == id)
|
||||
if (m_requests[i].m_protocol->getId() == id)
|
||||
return PROTOCOL_STATE_RUNNING; // we can say it's running
|
||||
}
|
||||
return PROTOCOL_STATE_TERMINATED; // else, it's already finished
|
||||
@ -571,13 +574,13 @@ ProtocolState ProtocolManager::getProtocolState(Protocol* protocol)
|
||||
// FIXME Does this need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].m_protocol == protocol) // the protocol is known
|
||||
return m_protocols.getData()[i].m_state;
|
||||
if (m_protocols.getData()[i] == protocol) // the protocol is known
|
||||
return m_protocols.getData()[i]->getState();
|
||||
}
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
// the protocol is going to be started
|
||||
if (m_requests[i].m_protocol_info.m_protocol == protocol)
|
||||
if (m_requests[i].m_protocol == protocol)
|
||||
return PROTOCOL_STATE_RUNNING; // we can say it's running
|
||||
}
|
||||
// we don't know this protocol at all, it's finished
|
||||
@ -594,8 +597,8 @@ uint32_t ProtocolManager::getProtocolID(Protocol* protocol)
|
||||
// FIXME: Does this need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].m_protocol == protocol)
|
||||
return m_protocols.getData()[i].m_id;
|
||||
if (m_protocols.getData()[i] == protocol)
|
||||
return m_protocols.getData()[i]->getId();
|
||||
}
|
||||
return 0;
|
||||
} // getProtocolID
|
||||
@ -610,8 +613,8 @@ Protocol* ProtocolManager::getProtocol(uint32_t id)
|
||||
// FIXME: does m_protocols need to be locked??
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].m_id == id)
|
||||
return m_protocols.getData()[i].m_protocol;
|
||||
if (m_protocols.getData()[i]->getId() == id)
|
||||
return m_protocols.getData()[i];
|
||||
}
|
||||
return NULL;
|
||||
} // getProtocol
|
||||
@ -626,8 +629,8 @@ Protocol* ProtocolManager::getProtocol(ProtocolType type)
|
||||
// FIXME: Does m_protocols need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols.getData()[i].m_protocol->getProtocolType() == type)
|
||||
return m_protocols.getData()[i].m_protocol;
|
||||
if (m_protocols.getData()[i]->getProtocolType() == type)
|
||||
return m_protocols.getData()[i];
|
||||
}
|
||||
return NULL;
|
||||
} // getProtocol
|
||||
@ -657,12 +660,19 @@ int ProtocolManager::exit()
|
||||
} // exit
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::assignProtocolId(ProtocolInfo* protocol_info)
|
||||
/** \brief Assign an id to a protocol.
|
||||
* This function will assign m_next_protocol_id as the protocol id.
|
||||
* This id starts at 0 at the beginning and is increased by 1 each time
|
||||
* a protocol starts.
|
||||
* \param protocol_info : The protocol info that needs an id.
|
||||
*/
|
||||
uint32_t ProtocolManager::getNextProtocolId()
|
||||
{
|
||||
pthread_mutex_lock(&m_id_mutex);
|
||||
protocol_info->m_id = m_next_protocol_id;
|
||||
uint32_t id = m_next_protocol_id;
|
||||
m_next_protocol_id++;
|
||||
pthread_mutex_unlock(&m_id_mutex);
|
||||
} // assignProtocolId
|
||||
return id;
|
||||
} // getNextProtocolId
|
||||
|
||||
|
||||
|
@ -37,17 +37,6 @@ class STKPeer;
|
||||
|
||||
#define TIME_TO_KEEP_EVENTS 1.0
|
||||
|
||||
/** \enum PROTOCOL_STATE
|
||||
* \brief Defines the three states that a protocol can have.
|
||||
*/
|
||||
enum ProtocolState
|
||||
{
|
||||
PROTOCOL_STATE_INITIALISING, //!< The protocol is waiting to be started
|
||||
PROTOCOL_STATE_RUNNING, //!< The protocol is being updated everytime.
|
||||
PROTOCOL_STATE_PAUSED, //!< The protocol is paused.
|
||||
PROTOCOL_STATE_TERMINATED //!< The protocol is terminated/does not exist.
|
||||
}; // ProtocolState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \enum ProtocolRequestType
|
||||
* \brief Defines actions that can be done about protocols.
|
||||
@ -63,29 +52,32 @@ enum ProtocolRequestType
|
||||
PROTOCOL_REQUEST_TERMINATE //!< Terminate a protocol
|
||||
}; // ProtocolRequestType
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \struct ProtocolInfo
|
||||
* \brief Stores the information needed to manage protocols
|
||||
*/
|
||||
typedef struct ProtocolInfo
|
||||
{
|
||||
ProtocolState m_state; //!< The state of the protocol
|
||||
Protocol* m_protocol; //!< A pointer to the protocol
|
||||
uint32_t m_id; //!< The unique id of the protocol
|
||||
} ProtocolInfo;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \struct ProtocolRequest
|
||||
* \brief Represents a request to do an action about a protocol.
|
||||
*/
|
||||
typedef struct ProtocolRequest
|
||||
class ProtocolRequest
|
||||
{
|
||||
public:
|
||||
/** The type of request. */
|
||||
ProtocolRequestType m_type;
|
||||
|
||||
/** The concerned protocol information. */
|
||||
ProtocolInfo m_protocol_info;
|
||||
} ProtocolRequest;
|
||||
Protocol *m_protocol;
|
||||
|
||||
public:
|
||||
ProtocolRequest(ProtocolRequestType type, Protocol *protocol)
|
||||
{
|
||||
m_type = type;
|
||||
m_protocol = protocol;
|
||||
} // ProtocolRequest
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the request type. */
|
||||
ProtocolRequestType getType() const { return m_type; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the protocol for this request. */
|
||||
Protocol *getProtocol() { return m_protocol; }
|
||||
}; // class ProtocolRequest;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \struct ProtocolRequest
|
||||
@ -153,40 +145,33 @@ class ProtocolManager : public AbstractSingleton<ProtocolManager>,
|
||||
* \brief Destructor
|
||||
*/
|
||||
virtual ~ProtocolManager();
|
||||
/*!
|
||||
* \brief Assign an id to a protocol.
|
||||
* This function will assign m_next_protocol_id as the protocol id.
|
||||
* This id starts at 0 at the beginning and is increased by 1 each time
|
||||
* a protocol starts.
|
||||
* \param protocol_info : The protocol info that needs an id.
|
||||
*/
|
||||
void assignProtocolId(ProtocolInfo* protocol_info);
|
||||
uint32_t getNextProtocolId();
|
||||
|
||||
virtual void startProtocol(ProtocolInfo &protocol);
|
||||
virtual void startProtocol(Protocol *protocol);
|
||||
/*!
|
||||
* \brief Stops a protocol.
|
||||
* Coes nothing. Noone can stop running protocols for now.
|
||||
* \param protocol : ProtocolInfo to stop.
|
||||
* \param protocol : Protocol to stop.
|
||||
*/
|
||||
virtual void stopProtocol(ProtocolInfo protocol);
|
||||
virtual void stopProtocol(Protocol *protocol);
|
||||
/*!
|
||||
* \brief Pauses a protocol.
|
||||
* Pauses a protocol and tells it that it's being paused.
|
||||
* \param protocol : ProtocolInfo to pause.
|
||||
* \param protocol : Protocol to pause.
|
||||
*/
|
||||
virtual void pauseProtocol(ProtocolInfo protocol);
|
||||
virtual void pauseProtocol(Protocol *protocol);
|
||||
/*!
|
||||
* \brief Unpauses a protocol.
|
||||
* Unpauses a protocol and notifies it.
|
||||
* \param protocol : ProtocolInfo to unpause.
|
||||
* \param protocol : Protocol to unpause.
|
||||
*/
|
||||
virtual void unpauseProtocol(ProtocolInfo protocol);
|
||||
virtual void unpauseProtocol(Protocol *protocol);
|
||||
/*!
|
||||
* \brief Notes that a protocol is terminated.
|
||||
* Remove a protocol from the protocols vector.
|
||||
* \param protocol : ProtocolInfo concerned.
|
||||
* \param protocol : Protocol concerned.
|
||||
*/
|
||||
virtual void protocolTerminated(ProtocolInfo protocol);
|
||||
virtual void protocolTerminated(Protocol *protocol);
|
||||
|
||||
bool sendEvent(EventProcessingInfo* event, bool synchronous);
|
||||
|
||||
@ -194,7 +179,7 @@ class ProtocolManager : public AbstractSingleton<ProtocolManager>,
|
||||
/** Contains the running protocols.
|
||||
* This stores the protocols that are either running or paused, their
|
||||
* state and their unique id. */
|
||||
Synchronised<std::vector<ProtocolInfo> >m_protocols;
|
||||
Synchronised<std::vector<Protocol*> >m_protocols;
|
||||
|
||||
/** Contains the network events to pass to protocols. */
|
||||
Synchronised<std::vector<EventProcessingInfo> > m_events_to_process;
|
||||
|
@ -58,7 +58,7 @@ void ClientLobbyRoomProtocol::requestKartSelection(std::string kart_name)
|
||||
NetworkString request(6+1+kart_name.size());
|
||||
// 0x02 : kart selection request, size_token (4), token, size kart name, kart name
|
||||
request.ai8(0x02).ai8(4).ai32(m_server->getClientServerToken()).add(kart_name);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
sendMessage(request, true);
|
||||
} // requestKartSelection
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -68,7 +68,7 @@ void ClientLobbyRoomProtocol::voteMajor(uint8_t major)
|
||||
NetworkString request(8);
|
||||
// 0xc0 : major vote, size_token (4), token, size major(1),major
|
||||
request.ai8(0xc0).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(major);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
sendMessage(request, true);
|
||||
} // voteMajor
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -78,7 +78,7 @@ void ClientLobbyRoomProtocol::voteRaceCount(uint8_t count)
|
||||
NetworkString request(8);
|
||||
// 0xc0 : race count vote, size_token (4), token, size race count(1), count
|
||||
request.ai8(0xc1).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(count);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
sendMessage(request, true);
|
||||
} // voteRaceCount
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -88,7 +88,7 @@ void ClientLobbyRoomProtocol::voteMinor(uint8_t minor)
|
||||
NetworkString request(8);
|
||||
// 0xc0 : minor vote, size_token (4), token, size minor(1),minor
|
||||
request.ai8(0xc2).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(minor);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
sendMessage(request, true);
|
||||
} // voteMinor
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -98,7 +98,7 @@ void ClientLobbyRoomProtocol::voteTrack(std::string track, uint8_t track_nb)
|
||||
NetworkString request(8+1+track.size());
|
||||
// 0xc0 : major vote, size_token (4), token, size track, track, size #track, #track
|
||||
request.ai8(0xc3).ai8(4).ai32(m_server->getClientServerToken()).add(track).ai8(1).ai8(track_nb);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
sendMessage(request, true);
|
||||
} // voteTrack
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -108,7 +108,7 @@ void ClientLobbyRoomProtocol::voteReversed(bool reversed, uint8_t track_nb)
|
||||
NetworkString request(9);
|
||||
// 0xc0 : major vote, size_token (4), token, size reversed(1),reversed, size #track, #track
|
||||
request.ai8(0xc4).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(reversed).ai8(1).ai8(track_nb);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
sendMessage(request, true);
|
||||
} // voteReversed
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -118,7 +118,7 @@ void ClientLobbyRoomProtocol::voteLaps(uint8_t laps, uint8_t track_nb)
|
||||
NetworkString request(10);
|
||||
// 0xc0 : major vote, size_token (4), token, size laps(1),laps, size #track, #track
|
||||
request.ai8(0xc5).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(laps).ai8(1).ai8(track_nb);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
sendMessage(request, true);
|
||||
} // voteLaps
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -209,7 +209,7 @@ bool ClientLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
|
||||
NetworkManager::getInstance()->removePeer(m_server);
|
||||
m_server = NULL;
|
||||
NetworkManager::getInstance()->disconnected();
|
||||
m_listener->requestTerminate(this);
|
||||
ProtocolManager::getInstance()->requestTerminate(this);
|
||||
NetworkManager::getInstance()->reset();
|
||||
// probably the same as m_server
|
||||
NetworkManager::getInstance()->removePeer(event->getPeer());
|
||||
@ -235,7 +235,7 @@ void ClientLobbyRoomProtocol::update()
|
||||
NetworkString ns(6);
|
||||
// 1 (connection request), 4 (size of id), global id
|
||||
ns.ai8(1).ai8(4).ai32(PlayerManager::getCurrentOnlineId());
|
||||
m_listener->sendMessage(this, ns);
|
||||
sendMessage(ns);
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
}
|
||||
break;
|
||||
@ -265,7 +265,7 @@ void ClientLobbyRoomProtocol::update()
|
||||
break;
|
||||
case DONE:
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
ProtocolManager::getInstance()->requestTerminate(this);
|
||||
break;
|
||||
case EXITING:
|
||||
break;
|
||||
@ -546,7 +546,7 @@ void ClientLobbyRoomProtocol::startGame(Event* event)
|
||||
if (token == NetworkManager::getInstance()->getPeers()[0]->getClientServerToken())
|
||||
{
|
||||
m_state = PLAYING;
|
||||
m_listener->requestStart(new StartGameProtocol(m_setup));
|
||||
ProtocolManager::getInstance()->requestStart(new StartGameProtocol(m_setup));
|
||||
Log::error("ClientLobbyRoomProtocol", "Starting new game");
|
||||
}
|
||||
else
|
||||
@ -616,21 +616,21 @@ void ClientLobbyRoomProtocol::raceFinished(Event* event)
|
||||
|
||||
// stop race protocols
|
||||
Protocol* protocol = NULL;
|
||||
protocol = m_listener->getProtocol(PROTOCOL_CONTROLLER_EVENTS);
|
||||
protocol = ProtocolManager::getInstance()->getProtocol(PROTOCOL_CONTROLLER_EVENTS);
|
||||
if (protocol)
|
||||
m_listener->requestTerminate(protocol);
|
||||
ProtocolManager::getInstance()->requestTerminate(protocol);
|
||||
else
|
||||
Log::error("ClientLobbyRoomProtocol", "No controller events protocol registered.");
|
||||
|
||||
protocol = m_listener->getProtocol(PROTOCOL_KART_UPDATE);
|
||||
protocol = ProtocolManager::getInstance() ->getProtocol(PROTOCOL_KART_UPDATE);
|
||||
if (protocol)
|
||||
m_listener->requestTerminate(protocol);
|
||||
ProtocolManager::getInstance()->requestTerminate(protocol);
|
||||
else
|
||||
Log::error("ClientLobbyRoomProtocol", "No kart update protocol registered.");
|
||||
|
||||
protocol = m_listener->getProtocol(PROTOCOL_GAME_EVENTS);
|
||||
protocol = ProtocolManager::getInstance()->getProtocol(PROTOCOL_GAME_EVENTS);
|
||||
if (protocol)
|
||||
m_listener->requestTerminate(protocol);
|
||||
ProtocolManager::getInstance()->requestTerminate(protocol);
|
||||
else
|
||||
Log::error("ClientLobbyRoomProtocol", "No game events protocol registered.");
|
||||
|
||||
|
@ -19,7 +19,6 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
void voteTrack(std::string track, uint8_t track_nb = 0);
|
||||
void voteReversed(bool reversed, uint8_t track_nb = 0);
|
||||
void voteLaps(uint8_t laps, uint8_t track_nb = 0);
|
||||
void sendMessage(std::string message);
|
||||
void leave();
|
||||
|
||||
virtual bool notifyEvent(Event* event);
|
||||
|
@ -31,18 +31,18 @@
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ConnectToPeer::ConnectToPeer(uint32_t peer_id) :
|
||||
Protocol(NULL, PROTOCOL_CONNECTION)
|
||||
ConnectToPeer::ConnectToPeer(uint32_t peer_id)
|
||||
: Protocol(NULL, PROTOCOL_CONNECTION)
|
||||
{
|
||||
m_peer_id = peer_id;
|
||||
m_state = NONE;
|
||||
}
|
||||
} // ConnectToPeer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ConnectToPeer::~ConnectToPeer()
|
||||
{
|
||||
}
|
||||
} // ~ConnectToPeer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@ -54,17 +54,17 @@ bool ConnectToPeer::notifyEventAsynchronous(Event* event)
|
||||
m_state = CONNECTED; // we received a message, we are connected
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // notifyEventAsynchronous
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ConnectToPeer::setup()
|
||||
{
|
||||
m_state = NONE;
|
||||
m_public_address.clear();
|
||||
m_peer_address.clear();
|
||||
m_current_protocol_id = 0;
|
||||
}
|
||||
m_current_protocol = NULL;
|
||||
m_state = NONE;
|
||||
} // setup
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@ -74,13 +74,14 @@ void ConnectToPeer::asynchronousUpdate()
|
||||
{
|
||||
case NONE:
|
||||
{
|
||||
m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_peer_id, &m_peer_address));
|
||||
m_current_protocol = new GetPeerAddress(m_peer_id, &m_peer_address);
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
m_state = WAITING_PEER_ADDRESS;
|
||||
break;
|
||||
}
|
||||
case WAITING_PEER_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id)
|
||||
== PROTOCOL_STATE_TERMINATED) // we know the peer address
|
||||
// Wait till we know the peer address
|
||||
if (m_current_protocol->getState()== PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
if (m_peer_address.getIP() != 0 && m_peer_address.getPort() != 0)
|
||||
{
|
||||
@ -88,22 +89,22 @@ void ConnectToPeer::asynchronousUpdate()
|
||||
if (m_peer_address.getIP() == NetworkManager::getInstance()->getPublicAddress().getIP())
|
||||
{
|
||||
// just send a broadcast packet with the string aloha_stk inside, the client will know our ip address and will connect
|
||||
STKHost* host = NetworkManager::getInstance()->getHost();
|
||||
TransportAddress broadcast_address;
|
||||
broadcast_address.setIP(-1); // 255.255.255.255
|
||||
broadcast_address.setPort(m_peer_address.getPort()); // 0b10101100000101101101111111111111; // for test
|
||||
char data[] = "aloha_stk\0";
|
||||
host->sendRawPacket((uint8_t*)(data), 10, broadcast_address);
|
||||
STKHost::get()->sendRawPacket((uint8_t*)(data), 10, broadcast_address);
|
||||
Log::info("ConnectToPeer", "Broadcast aloha sent.");
|
||||
StkTime::sleep(1);
|
||||
broadcast_address.setIP(0x7f000001); // 127.0.0.1 (localhost)
|
||||
broadcast_address.setPort(m_peer_address.getPort());
|
||||
host->sendRawPacket((uint8_t*)(data), 10, broadcast_address);
|
||||
STKHost::get()->sendRawPacket((uint8_t*)(data), 10, broadcast_address);
|
||||
Log::info("ConnectToPeer", "Broadcast aloha to self.");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_protocol_id = m_listener->requestStart(new PingProtocol(m_peer_address, 2.0));
|
||||
m_current_protocol = new PingProtocol(m_peer_address, 2.0);
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
}
|
||||
m_state = CONNECTING;
|
||||
}
|
||||
@ -120,18 +121,22 @@ void ConnectToPeer::asynchronousUpdate()
|
||||
{
|
||||
// the ping protocol is there for NAT traversal (disabled when connecting to LAN peer)
|
||||
if (m_peer_address != NetworkManager::getInstance()->getPublicAddress())
|
||||
m_listener->requestTerminate( m_listener->getProtocol(m_current_protocol_id)); // kill the ping protocol because we're connected
|
||||
{
|
||||
// Kill the ping protocol because we're connected
|
||||
ProtocolManager::getInstance()
|
||||
->requestTerminate(m_current_protocol);
|
||||
}
|
||||
m_state = DONE;
|
||||
break;
|
||||
}
|
||||
case DONE:
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
ProtocolManager::getInstance()->requestTerminate(this);
|
||||
break;
|
||||
case EXITING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // asynchronousUpdate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -38,7 +38,9 @@ class ConnectToPeer : public Protocol, public CallbackObject
|
||||
TransportAddress m_peer_address;
|
||||
TransportAddress m_public_address;
|
||||
uint32_t m_peer_id;
|
||||
uint32_t m_current_protocol_id;
|
||||
|
||||
/** Pointer to the protocol which is monitored for state changes. */
|
||||
Protocol *m_current_protocol;
|
||||
|
||||
enum STATE
|
||||
{
|
||||
|
@ -86,9 +86,9 @@ bool ConnectToServer::notifyEventAsynchronous(Event* event)
|
||||
void ConnectToServer::setup()
|
||||
{
|
||||
Log::info("ConnectToServer", "SETUP");
|
||||
m_state = NONE;
|
||||
m_server_address.clear();
|
||||
m_current_protocol_id = 0;
|
||||
m_state = NONE;
|
||||
m_current_protocol = NULL;
|
||||
} // setup
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -99,46 +99,45 @@ void ConnectToServer::asynchronousUpdate()
|
||||
case NONE:
|
||||
{
|
||||
Log::info("ConnectToServer", "Protocol starting");
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(new GetPublicAddress());
|
||||
m_current_protocol = new GetPublicAddress();
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
m_state = GETTING_SELF_ADDRESS;
|
||||
break;
|
||||
}
|
||||
case GETTING_SELF_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) ==
|
||||
PROTOCOL_STATE_TERMINATED) // now we know the public addr
|
||||
// Wait till we know the public address
|
||||
if (m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
m_state = SHOWING_SELF_ADDRESS;
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(new ShowPublicAddress());
|
||||
m_current_protocol = new ShowPublicAddress();
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
Log::info("ConnectToServer", "Public address known");
|
||||
}
|
||||
break;
|
||||
case SHOWING_SELF_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) ==
|
||||
PROTOCOL_STATE_TERMINATED)
|
||||
if (m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
// now our public address is in the database
|
||||
Log::info("ConnectToServer", "Public address shown");
|
||||
if (m_quick_join)
|
||||
{
|
||||
m_current_protocol_id = m_listener->requestStart(
|
||||
new QuickJoinProtocol(&m_server_address,
|
||||
&m_server_id) );
|
||||
m_current_protocol = new QuickJoinProtocol(&m_server_address,
|
||||
&m_server_id);
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_protocol_id = m_listener->requestStart(
|
||||
new GetPeerAddress(m_host_id,
|
||||
&m_server_address) );
|
||||
m_current_protocol = new GetPeerAddress(m_host_id,
|
||||
&m_server_address);
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
m_state = GETTING_SERVER_ADDRESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GETTING_SERVER_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) ==
|
||||
PROTOCOL_STATE_TERMINATED) // we know the server address
|
||||
// Wait till we know the server address
|
||||
if (m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
Log::info("ConnectToServer", "Server's address known");
|
||||
// we're in the same lan (same public ip address) !!
|
||||
@ -149,14 +148,12 @@ void ConnectToServer::asynchronousUpdate()
|
||||
"Server appears to be in the same LAN.");
|
||||
}
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(
|
||||
new RequestConnection(m_server_id));
|
||||
m_current_protocol = new RequestConnection(m_server_id);
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
}
|
||||
break;
|
||||
case REQUESTING_CONNECTION:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) ==
|
||||
PROTOCOL_STATE_TERMINATED)
|
||||
if (m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
// Server knows we want to connect
|
||||
Log::info("ConnectToServer", "Connection request made");
|
||||
@ -167,8 +164,8 @@ void ConnectToServer::asynchronousUpdate()
|
||||
m_state = HIDING_ADDRESS;
|
||||
Log::error("ConnectToServer", "Server address is %s",
|
||||
m_server_address.toString().c_str());
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(new HidePublicAddress());
|
||||
m_current_protocol = new HidePublicAddress();
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
return;
|
||||
}
|
||||
if (m_server_address.getIP() == NetworkManager::getInstance()
|
||||
@ -180,8 +177,8 @@ void ConnectToServer::asynchronousUpdate()
|
||||
else
|
||||
{
|
||||
m_state = CONNECTING;
|
||||
m_current_protocol_id = m_listener->requestStart(
|
||||
new PingProtocol(m_server_address, 2.0));
|
||||
m_current_protocol = new PingProtocol(m_server_address, 2.0);
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -201,30 +198,29 @@ void ConnectToServer::asynchronousUpdate()
|
||||
{
|
||||
Log::info("ConnectToServer", "Connected");
|
||||
// Kill the ping protocol because we're connected
|
||||
m_listener->requestTerminate(
|
||||
m_listener->getProtocol(m_current_protocol_id));
|
||||
m_current_protocol_id =
|
||||
m_listener->requestStart(new HidePublicAddress());
|
||||
ProtocolManager::getInstance()->requestTerminate(m_current_protocol);
|
||||
m_current_protocol = new HidePublicAddress();
|
||||
ProtocolManager::getInstance()->requestStart(m_current_protocol);
|
||||
ClientNetworkManager::getInstance()->setConnected(true);
|
||||
m_state = HIDING_ADDRESS;
|
||||
break;
|
||||
}
|
||||
case HIDING_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id)
|
||||
== PROTOCOL_STATE_TERMINATED) // we have hidden our address
|
||||
// Wait till we have hidden our address
|
||||
if (m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
Log::info("ConnectToServer", "Address hidden");
|
||||
m_state = DONE;
|
||||
// lobby room protocol if we're connected only
|
||||
if (ClientNetworkManager::getInstance()->isConnected())
|
||||
{
|
||||
m_listener->requestStart(
|
||||
ProtocolManager::getInstance()->requestStart(
|
||||
new ClientLobbyRoomProtocol(m_server_address));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DONE:
|
||||
m_listener->requestTerminate(this);
|
||||
ProtocolManager::getInstance()->requestTerminate(this);
|
||||
m_state = EXITING;
|
||||
break;
|
||||
case EXITING:
|
||||
@ -240,7 +236,7 @@ void ConnectToServer::handleSameLAN()
|
||||
{
|
||||
// just send a broadcast packet, the client will know our
|
||||
// ip address and will connect
|
||||
STKHost* host = NetworkManager::getInstance()->getHost();
|
||||
STKHost* host = STKHost::get();
|
||||
host->stopListening(); // stop the listening
|
||||
|
||||
TransportAddress broadcast_address;
|
||||
|
@ -30,7 +30,9 @@ private:
|
||||
TransportAddress m_server_address;
|
||||
uint32_t m_server_id;
|
||||
uint32_t m_host_id;
|
||||
uint32_t m_current_protocol_id;
|
||||
|
||||
/** Protocol currently being monitored. */
|
||||
Protocol *m_current_protocol;
|
||||
bool m_quick_join;
|
||||
|
||||
enum State
|
||||
|
@ -37,7 +37,7 @@ void ControllerEventsProtocol::setup()
|
||||
m_self_controller_index = i;
|
||||
}
|
||||
STKPeer* peer = NULL;
|
||||
if (m_listener->isServer())
|
||||
if (ProtocolManager::getInstance()->isServer())
|
||||
{
|
||||
for (unsigned int j = 0; j < peers.size(); j++)
|
||||
{
|
||||
@ -114,7 +114,7 @@ bool ControllerEventsProtocol::notifyEventAsynchronous(Event* event)
|
||||
Log::warn("ControllerEventProtocol", "Couldn't have a client id.");
|
||||
return true;
|
||||
}
|
||||
if (m_listener->isServer())
|
||||
if (ProtocolManager::getInstance()->isServer())
|
||||
{
|
||||
// notify everybody of the event :
|
||||
for (unsigned int i = 0; i < m_controllers.size(); i++)
|
||||
@ -124,12 +124,13 @@ bool ControllerEventsProtocol::notifyEventAsynchronous(Event* event)
|
||||
NetworkString ns2(4+pure_message.size());
|
||||
ns2.ai32(m_controllers[i].second->getClientServerToken());
|
||||
ns2 += pure_message;
|
||||
m_listener->sendMessage(this, m_controllers[i].second, ns2, false);
|
||||
ProtocolManager::getInstance()
|
||||
->sendMessage(this, m_controllers[i].second, ns2, false);
|
||||
//Log::info("ControllerEventsProtocol", "Sizes are %d and %d", ns2.size(), pure_message.size());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // notifyEventAsynchronous
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -140,9 +141,9 @@ void ControllerEventsProtocol::update()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ControllerEventsProtocol::controllerAction(Controller* controller,
|
||||
PlayerAction action, int value)
|
||||
PlayerAction action, int value)
|
||||
{
|
||||
assert(!m_listener->isServer());
|
||||
assert(!ProtocolManager::getInstance()->isServer());
|
||||
|
||||
KartControl* controls = controller->getControls();
|
||||
uint8_t serialized_1 = 0;
|
||||
@ -168,7 +169,7 @@ void ControllerEventsProtocol::controllerAction(Controller* controller,
|
||||
ns.ai8((uint8_t)(action)).ai32(value);
|
||||
|
||||
Log::info("ControllerEventsProtocol", "Action %d value %d", action, value);
|
||||
m_listener->sendMessage(this, ns, false); // send message to server
|
||||
sendMessage(ns, false); // send message to server
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,7 +92,7 @@ void GameEventsProtocol::collectedItem(Item* item, AbstractKart* kart)
|
||||
powerup = (((int)(kart->getPowerup()->getType()) << 4)&0xf0) + (kart->getPowerup()->getNum()&0x0f);
|
||||
|
||||
ns.ai8(0x01).ai32(item->getItemId()).ai8(powerup).ai8(player_profile->race_id); // send item,
|
||||
m_listener->sendMessage(this, peers[i], ns, true); // reliable
|
||||
ProtocolManager::getInstance()->sendMessage(this, peers[i], ns, true); // reliable
|
||||
Log::info("GameEventsProtocol", "Notified a peer that a kart collected item %d.", (int)(kart->getPowerup()->getType()));
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ void GetPeerAddress::asynchronousUpdate()
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,8 +85,7 @@ void GetPublicAddress::createStunRequest()
|
||||
assert(res != NULL);
|
||||
struct sockaddr_in* current_interface = (struct sockaddr_in*)(res->ai_addr);
|
||||
m_stun_server_ip = ntohl(current_interface->sin_addr.s_addr);
|
||||
m_transaction_host = new STKHost();
|
||||
m_transaction_host->setupClient(1, 1, 0, 0);
|
||||
m_transaction_host = new Network(1, 1, 0, 0);
|
||||
|
||||
// Assemble the message for the stun server
|
||||
NetworkString s(21);
|
||||
@ -194,7 +193,7 @@ std::string GetPublicAddress::parseStunResponse()
|
||||
|
||||
// The address and the port are known, so the connection can be closed
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
|
||||
return "";
|
||||
} // parseStunResponse
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
class STKHost;
|
||||
class Network;
|
||||
|
||||
class GetPublicAddress : public Protocol
|
||||
{
|
||||
@ -54,7 +54,7 @@ class GetPublicAddress : public Protocol
|
||||
STATE m_state;
|
||||
uint8_t m_stun_tansaction_id[12];
|
||||
uint32_t m_stun_server_ip;
|
||||
STKHost* m_transaction_host;
|
||||
Network* m_transaction_host;
|
||||
};
|
||||
|
||||
#endif // GET_PUBLIC_ADDRESS_HPP
|
||||
|
@ -74,6 +74,6 @@ void HidePublicAddress::asynchronousUpdate()
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ void KartUpdateProtocol::update()
|
||||
if (current_time > time + 0.1) // 10 updates per second
|
||||
{
|
||||
time = current_time;
|
||||
if (m_listener->isServer())
|
||||
if (ProtocolManager::getInstance()->isServer())
|
||||
{
|
||||
NetworkString ns(4+m_karts.size()*32);
|
||||
ns.af( World::getWorld()->getTime());
|
||||
@ -89,9 +89,11 @@ void KartUpdateProtocol::update()
|
||||
ns.ai32( kart->getWorldKartId());
|
||||
ns.af(v[0]).af(v[1]).af(v[2]); // add position
|
||||
ns.af(quat.x()).af(quat.y()).af(quat.z()).af(quat.w()); // add rotation
|
||||
Log::verbose("KartUpdateProtocol", "Sending %d's positions %f %f %f", kart->getWorldKartId(), v[0], v[1], v[2]);
|
||||
Log::verbose("KartUpdateProtocol",
|
||||
"Sending %d's positions %f %f %f",
|
||||
kart->getWorldKartId(), v[0], v[1], v[2]);
|
||||
}
|
||||
m_listener->sendMessage(this, ns, false);
|
||||
sendMessage(ns, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -103,8 +105,10 @@ void KartUpdateProtocol::update()
|
||||
ns.ai32( kart->getWorldKartId());
|
||||
ns.af(v[0]).af(v[1]).af(v[2]); // add position
|
||||
ns.af(quat.x()).af(quat.y()).af(quat.z()).af(quat.w()); // add rotation
|
||||
Log::verbose("KartUpdateProtocol", "Sending %d's positions %f %f %f", kart->getWorldKartId(), v[0], v[1], v[2]);
|
||||
m_listener->sendMessage(this, ns, false);
|
||||
Log::verbose("KartUpdateProtocol",
|
||||
"Sending %d's positions %f %f %f",
|
||||
kart->getWorldKartId(), v[0], v[1], v[2]);
|
||||
sendMessage(ns, false);
|
||||
}
|
||||
}
|
||||
switch(pthread_mutex_trylock(&m_positions_updates_mutex))
|
||||
@ -113,7 +117,8 @@ void KartUpdateProtocol::update()
|
||||
while (!m_next_positions.empty())
|
||||
{
|
||||
uint32_t id = m_karts_ids.back();
|
||||
if (id != m_self_kart_index || m_listener->isServer()) // server takes all updates
|
||||
if (id != m_self_kart_index ||
|
||||
ProtocolManager::getInstance()->isServer()) // server takes all updates
|
||||
{
|
||||
Vec3 pos = m_next_positions.back();
|
||||
btTransform transform = m_karts[id]->getBody()->getInterpolationWorldTransform();
|
||||
|
@ -43,7 +43,7 @@ void PingProtocol::asynchronousUpdate()
|
||||
{
|
||||
m_last_ping_time = StkTime::getRealTime();
|
||||
uint8_t data = 0;
|
||||
NetworkManager::getInstance()->getHost()->sendRawPacket(&data, 1, m_ping_dst);
|
||||
STKHost::get()->sendRawPacket(&data, 1, m_ping_dst);
|
||||
Log::info("PingProtocol", "Ping message sent");
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,6 @@ void QuickJoinProtocol::asynchronousUpdate()
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ void RequestConnection::asynchronousUpdate()
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
break;
|
||||
case EXITING:
|
||||
break;
|
||||
|
@ -22,13 +22,14 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/network_world.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 "network/protocols/start_game_protocol.hpp"
|
||||
#include "network/server_network_manager.hpp"
|
||||
#include "network/server_console.hpp"
|
||||
#include "online/online_profile.hpp"
|
||||
#include "online/request_manager.hpp"
|
||||
#include "utils/log.hpp"
|
||||
@ -106,19 +107,21 @@ void ServerLobbyRoomProtocol::update()
|
||||
switch (m_state)
|
||||
{
|
||||
case NONE:
|
||||
m_current_protocol_id = m_listener->requestStart(new GetPublicAddress());
|
||||
m_current_protocol = new GetPublicAddress();
|
||||
m_current_protocol->requestStart();
|
||||
m_state = GETTING_PUBLIC_ADDRESS;
|
||||
break;
|
||||
case GETTING_PUBLIC_ADDRESS:
|
||||
if (m_listener->getProtocolState(m_current_protocol_id) == PROTOCOL_STATE_TERMINATED)
|
||||
if (m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
m_current_protocol_id = m_listener->requestStart(new StartServer());
|
||||
m_current_protocol = new StartServer();
|
||||
m_current_protocol->requestStart();
|
||||
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)
|
||||
if (m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED)
|
||||
{
|
||||
m_state = WORKING;
|
||||
Log::info("ServerLobbyRoomProtocol", "Server setup");
|
||||
@ -127,14 +130,17 @@ void ServerLobbyRoomProtocol::update()
|
||||
case WORKING:
|
||||
{
|
||||
checkIncomingConnectionRequests();
|
||||
if (m_in_race && World::getWorld() && NetworkWorld::getInstance<NetworkWorld>()->isRunning())
|
||||
if (m_in_race && World::getWorld() &&
|
||||
NetworkWorld::getInstance<NetworkWorld>()->isRunning())
|
||||
{
|
||||
checkRaceFinished();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case DONE:
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
break;
|
||||
case EXITING:
|
||||
break;
|
||||
@ -150,11 +156,12 @@ void ServerLobbyRoomProtocol::startGame()
|
||||
{
|
||||
NetworkString ns(6);
|
||||
ns.ai8(0x04).ai8(4).ai32(peers[i]->getClientServerToken()); // start game
|
||||
m_listener->sendMessage(this, peers[i], ns, true); // reliably
|
||||
sendMessage(peers[i], ns, true); // reliably
|
||||
}
|
||||
m_listener->requestStart(new StartGameProtocol(m_setup));
|
||||
Protocol *p = new StartGameProtocol(m_setup);
|
||||
p->requestStart();
|
||||
m_in_race = true;
|
||||
}
|
||||
} // startGame
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -165,10 +172,10 @@ void ServerLobbyRoomProtocol::startSelection()
|
||||
{
|
||||
NetworkString ns(6);
|
||||
ns.ai8(0x05).ai8(4).ai32(peers[i]->getClientServerToken()); // start selection
|
||||
m_listener->sendMessage(this, peers[i], ns, true); // reliably
|
||||
sendMessage(peers[i], ns, true); // reliably
|
||||
}
|
||||
m_selection_enabled = true;
|
||||
}
|
||||
} // startSelection
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -220,10 +227,11 @@ void ServerLobbyRoomProtocol::checkIncomingConnectionRequests()
|
||||
// now
|
||||
for (unsigned int i = 0; i < m_incoming_peers_ids.size(); i++)
|
||||
{
|
||||
m_listener->requestStart(new ConnectToPeer(m_incoming_peers_ids[i]));
|
||||
Protocol *p = new ConnectToPeer(m_incoming_peers_ids[i]);
|
||||
p->requestStart();
|
||||
}
|
||||
m_incoming_peers_ids.clear();
|
||||
}
|
||||
} // checkIncomingConnectionRequests
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -265,28 +273,28 @@ void ServerLobbyRoomProtocol::checkRaceFinished()
|
||||
NetworkString ns(6);
|
||||
ns.ai8(0x06).ai8(4).ai32(peers[i]->getClientServerToken());
|
||||
NetworkString total = ns + queue;
|
||||
m_listener->sendMessage(this, peers[i], total, true);
|
||||
sendMessage(peers[i], total, true);
|
||||
}
|
||||
Log::info("ServerLobbyRoomProtocol", "End of game message sent");
|
||||
m_in_race = false;
|
||||
|
||||
// stop race protocols
|
||||
Protocol* protocol = NULL;
|
||||
protocol = m_listener->getProtocol(PROTOCOL_CONTROLLER_EVENTS);
|
||||
protocol = ProtocolManager::getInstance()->getProtocol(PROTOCOL_CONTROLLER_EVENTS);
|
||||
if (protocol)
|
||||
m_listener->requestTerminate(protocol);
|
||||
protocol->requestTerminate();
|
||||
else
|
||||
Log::error("ClientLobbyRoomProtocol", "No controller events protocol registered.");
|
||||
|
||||
protocol = m_listener->getProtocol(PROTOCOL_KART_UPDATE);
|
||||
protocol = ProtocolManager::getInstance()->getProtocol(PROTOCOL_KART_UPDATE);
|
||||
if (protocol)
|
||||
m_listener->requestTerminate(protocol);
|
||||
protocol->requestTerminate();
|
||||
else
|
||||
Log::error("ClientLobbyRoomProtocol", "No kart update protocol registered.");
|
||||
|
||||
protocol = m_listener->getProtocol(PROTOCOL_GAME_EVENTS);
|
||||
protocol = ProtocolManager::getInstance()->getProtocol(PROTOCOL_GAME_EVENTS);
|
||||
if (protocol)
|
||||
m_listener->requestTerminate(protocol);
|
||||
protocol->requestTerminate();
|
||||
else
|
||||
Log::error("ClientLobbyRoomProtocol", "No game events protocol registered.");
|
||||
|
||||
@ -300,7 +308,7 @@ void ServerLobbyRoomProtocol::checkRaceFinished()
|
||||
{
|
||||
//Log::info("ServerLobbyRoomProtocol", "Phase is %d", World::getWorld()->getPhase());
|
||||
}
|
||||
}
|
||||
} // checkRaceFinished
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -311,7 +319,7 @@ void ServerLobbyRoomProtocol::kartDisconnected(Event* event)
|
||||
{
|
||||
NetworkString msg(3);
|
||||
msg.ai8(0x02).ai8(1).ai8(peer->getPlayerProfile()->race_id);
|
||||
m_listener->sendMessage(this, msg);
|
||||
sendMessage(msg);
|
||||
Log::info("ServerLobbyRoomProtocol", "Player disconnected : id %d",
|
||||
peer->getPlayerProfile()->race_id);
|
||||
m_setup->removePlayer(peer->getPlayerProfile()->race_id);
|
||||
@ -345,8 +353,7 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
uint32_t player_id = 0;
|
||||
player_id = data.getUInt32(1);
|
||||
// can we add the player ?
|
||||
if (m_setup->getPlayerCount() <
|
||||
ServerNetworkManager::getInstance()->getMaxPlayers()) //accept
|
||||
if (m_setup->getPlayerCount() < STKHost::getMaxPlayers()) //accept
|
||||
{
|
||||
// add the player to the game setup
|
||||
m_next_id = m_setup->getPlayerCount();
|
||||
@ -354,7 +361,7 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
NetworkString message(8);
|
||||
// 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, peer, message);
|
||||
ProtocolManager::getInstance()->sendMessageExcept(this, peer, message);
|
||||
|
||||
/// now answer to the peer that just connected
|
||||
RandomGenerator token_generator;
|
||||
@ -377,7 +384,7 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
if (players[i]->race_id != m_next_id && players[i]->user_profile->getID() != player_id)
|
||||
message_ack.ai8(1).ai8(players[i]->race_id).ai8(4).ai32(players[i]->user_profile->getID());
|
||||
}
|
||||
m_listener->sendMessage(this, peer, message_ack);
|
||||
sendMessage(peer, message_ack);
|
||||
|
||||
peer->setClientServerToken(token);
|
||||
|
||||
@ -396,7 +403,7 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
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, peer, message);
|
||||
sendMessage(peer, message);
|
||||
Log::verbose("ServerLobbyRoomProtocol", "Player refused");
|
||||
}
|
||||
}
|
||||
@ -433,7 +440,7 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
{
|
||||
NetworkString answer(3);
|
||||
answer.ai8(0x82).ai8(1).ai8(2); // selection still not started
|
||||
m_listener->sendMessage(this, peer, answer);
|
||||
sendMessage(peer, answer);
|
||||
return;
|
||||
}
|
||||
// check if somebody picked that kart
|
||||
@ -441,7 +448,7 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
{
|
||||
NetworkString answer(3);
|
||||
answer.ai8(0x82).ai8(1).ai8(0); // kart is already taken
|
||||
m_listener->sendMessage(this, peer, answer);
|
||||
sendMessage(peer, answer);
|
||||
return;
|
||||
}
|
||||
// check if this kart is authorized
|
||||
@ -449,7 +456,7 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
{
|
||||
NetworkString answer(3);
|
||||
answer.ai8(0x82).ai8(1).ai8(1); // kart is not authorized
|
||||
m_listener->sendMessage(this, peer, answer);
|
||||
sendMessage(peer, answer);
|
||||
return;
|
||||
}
|
||||
// send a kart update to everyone
|
||||
@ -458,7 +465,7 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
answer.ai8(0x03).ai8(1).ai8(peer->getPlayerProfile()->race_id);
|
||||
// kart name size, kart name
|
||||
answer.add(kart_name);
|
||||
m_listener->sendMessage(this, answer);
|
||||
sendMessage(answer);
|
||||
m_setup->setPlayerKart(peer->getPlayerProfile()->race_id, kart_name);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,38 @@
|
||||
|
||||
class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
{
|
||||
public:
|
||||
private:
|
||||
uint8_t m_next_id; //!< Next id to assign to a peer.
|
||||
std::vector<uint32_t> m_incoming_peers_ids;
|
||||
Protocol *m_current_protocol;
|
||||
bool m_selection_enabled;
|
||||
bool m_in_race;
|
||||
|
||||
|
||||
// connection management
|
||||
void kartDisconnected(Event* event);
|
||||
void connectionRequested(Event* event);
|
||||
// kart selection
|
||||
void kartSelectionRequested(Event* event);
|
||||
// race votes
|
||||
void playerMajorVote(Event* event);
|
||||
void playerRaceCountVote(Event* event);
|
||||
void playerMinorVote(Event* event);
|
||||
void playerTrackVote(Event* event);
|
||||
void playerReversedVote(Event* event);
|
||||
void playerLapsVote(Event* event);
|
||||
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
GETTING_PUBLIC_ADDRESS,
|
||||
LAUNCHING_SERVER,
|
||||
WORKING,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state; public:
|
||||
ServerLobbyRoomProtocol();
|
||||
virtual ~ServerLobbyRoomProtocol();
|
||||
|
||||
@ -19,35 +50,6 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
void checkIncomingConnectionRequests();
|
||||
void checkRaceFinished();
|
||||
|
||||
protected:
|
||||
// connection management
|
||||
void kartDisconnected(Event* event);
|
||||
void connectionRequested(Event* event);
|
||||
// kart selection
|
||||
void kartSelectionRequested(Event* event);
|
||||
// race votes
|
||||
void playerMajorVote(Event* event);
|
||||
void playerRaceCountVote(Event* event);
|
||||
void playerMinorVote(Event* event);
|
||||
void playerTrackVote(Event* event);
|
||||
void playerReversedVote(Event* event);
|
||||
void playerLapsVote(Event* event);
|
||||
|
||||
uint8_t m_next_id; //!< Next id to assign to a peer.
|
||||
std::vector<uint32_t> m_incoming_peers_ids;
|
||||
uint32_t m_current_protocol_id;
|
||||
bool m_selection_enabled;
|
||||
bool m_in_race;
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
GETTING_PUBLIC_ADDRESS,
|
||||
LAUNCHING_SERVER,
|
||||
WORKING,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
#endif // SERVER_LOBBY_ROOM_PROTOCOL_HPP
|
||||
|
@ -47,7 +47,7 @@ void ShowPublicAddress::asynchronousUpdate()
|
||||
|
||||
m_request->addParameter("address", addr.getIP());
|
||||
m_request->addParameter("port", addr.getPort());
|
||||
m_request->addParameter("private_port", NetworkManager::getInstance()->getHost()->getPort());
|
||||
m_request->addParameter("private_port", STKHost::get()->getPort());
|
||||
|
||||
Log::info("ShowPublicAddress", "Showing addr %s", addr.toString().c_str());
|
||||
|
||||
@ -81,6 +81,6 @@ void ShowPublicAddress::asynchronousUpdate()
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
}
|
||||
}
|
||||
} // asynchronousUpdate
|
||||
|
@ -51,7 +51,7 @@ bool StartGameProtocol::notifyEventAsynchronous(Event* event)
|
||||
Log::error("StartGameProtocol", "Bad token received.");
|
||||
return true;
|
||||
}
|
||||
if (m_listener->isServer() && ready) // on server, player is ready
|
||||
if (ProtocolManager::getInstance()->isServer() && ready) // on server, player is ready
|
||||
{
|
||||
Log::info("StartGameProtocol", "One of the players is ready.");
|
||||
m_player_states[peer->getPlayerProfile()] = READY;
|
||||
@ -59,7 +59,10 @@ bool StartGameProtocol::notifyEventAsynchronous(Event* event)
|
||||
if (m_ready_count == m_game_setup->getPlayerCount())
|
||||
{
|
||||
// everybody ready, synchronize
|
||||
SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>(m_listener->getProtocol(PROTOCOL_SYNCHRONIZATION));
|
||||
Protocol *p = ProtocolManager::getInstance()
|
||||
->getProtocol(PROTOCOL_SYNCHRONIZATION);
|
||||
SynchronizationProtocol* protocol =
|
||||
static_cast<SynchronizationProtocol*>(p);
|
||||
if (protocol)
|
||||
{
|
||||
protocol->startCountdown(5000); // 5 seconds countdown
|
||||
@ -94,7 +97,8 @@ void StartGameProtocol::update()
|
||||
if (m_state == NONE)
|
||||
{
|
||||
// if no synchronization protocol exists, create one
|
||||
m_listener->requestStart(new SynchronizationProtocol());
|
||||
Protocol *p = new SynchronizationProtocol();
|
||||
p->requestStart();
|
||||
Log::info("StartGameProtocol", "SynchronizationProtocol started.");
|
||||
// race startup sequence
|
||||
NetworkWorld::getInstance<NetworkWorld>()->start(); // builds it and starts
|
||||
@ -145,9 +149,13 @@ void StartGameProtocol::update()
|
||||
rki.setDifficulty(profile->difficulty);
|
||||
rki.setGlobalPlayerId(profile->race_id);
|
||||
// on the server, the race id must be the local one.
|
||||
rki.setLocalPlayerId(m_listener->isServer()?profile->race_id:(is_me?0:1));
|
||||
rki.setLocalPlayerId(ProtocolManager::getInstance()->isServer()
|
||||
? profile->race_id
|
||||
: (is_me ? 0 : 1) );
|
||||
rki.setHostId(profile->race_id);
|
||||
Log::info("StartGameProtocol", "Creating kart %s for Player#%d with race_id %d", profile->kart_name.c_str(), i, profile->race_id);
|
||||
Log::info("StartGameProtocol",
|
||||
"Creating kart %s for Player#%d with race_id %d",
|
||||
profile->kart_name.c_str(), i, profile->race_id);
|
||||
|
||||
if (!is_me)
|
||||
{
|
||||
@ -167,8 +175,9 @@ void StartGameProtocol::update()
|
||||
}
|
||||
else if (m_state == SYNCHRONIZATION_WAIT)
|
||||
{
|
||||
SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>
|
||||
(m_listener->getProtocol(PROTOCOL_SYNCHRONIZATION));
|
||||
Protocol *p = ProtocolManager::getInstance()
|
||||
->getProtocol(PROTOCOL_SYNCHRONIZATION);
|
||||
SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>(p);
|
||||
if (protocol)
|
||||
{
|
||||
// now the synchronization protocol exists.
|
||||
@ -190,19 +199,19 @@ void StartGameProtocol::update()
|
||||
// set karts into the network game setup
|
||||
NetworkManager::getInstance()->getGameSetup()->bindKartsToProfiles();
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
}
|
||||
}
|
||||
|
||||
void StartGameProtocol::ready() // on clients, means the loading is finished
|
||||
{
|
||||
if (!m_listener->isServer()) // if we're a client
|
||||
if (!ProtocolManager::getInstance()->isServer()) // if we're a client
|
||||
{
|
||||
assert(NetworkManager::getInstance()->getPeerCount() == 1);
|
||||
NetworkString ns(5);
|
||||
ns.ai32(NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()).ai8(1);
|
||||
Log::info("StartGameProtocol", "Player ready, notifying server.");
|
||||
m_listener->sendMessage(this, ns, true);
|
||||
sendMessage(ns, true);
|
||||
m_state = READY;
|
||||
m_ready = true;
|
||||
return;
|
||||
|
@ -49,7 +49,7 @@ void StartServer::asynchronousUpdate()
|
||||
|
||||
m_request->addParameter("address", addr.getIP());
|
||||
m_request->addParameter("port", addr.getPort());
|
||||
m_request->addParameter("private_port", NetworkManager::getInstance()->getHost()->getPort());
|
||||
m_request->addParameter("private_port", STKHost::get()->getPort());
|
||||
m_request->addParameter("max_players", UserConfigParams::m_server_max_players);
|
||||
|
||||
Log::info("ShowPublicAddress", "Showing addr %s", addr.toString().c_str());
|
||||
@ -84,7 +84,7 @@ void StartServer::asynchronousUpdate()
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
}
|
||||
} // asynchronousUpdate
|
||||
|
||||
|
@ -84,6 +84,6 @@ void StopServer::asynchronousUpdate()
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
requestTerminate();
|
||||
}
|
||||
}
|
||||
} // asynchronousUpdate
|
||||
|
@ -50,7 +50,7 @@ bool SynchronizationProtocol::notifyEventAsynchronous(Event* event)
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
assert(peers.size() > 0);
|
||||
|
||||
if (m_listener->isServer())
|
||||
if (ProtocolManager::getInstance()->isServer())
|
||||
{
|
||||
if (talk_id > peers.size())
|
||||
{
|
||||
@ -77,9 +77,11 @@ bool SynchronizationProtocol::notifyEventAsynchronous(Event* event)
|
||||
{
|
||||
NetworkString response(10);
|
||||
response.ai8(data.gui8(talk_id)).ai32(token).ai8(0).ai32(sequence);
|
||||
m_listener->sendMessage(this, peers[peer_id], response, false);
|
||||
sendMessage(peers[peer_id], response, false);
|
||||
Log::verbose("SynchronizationProtocol", "Answering sequence %u", sequence);
|
||||
if (data.size() == 14 && !m_listener->isServer()) // countdown time in the message
|
||||
|
||||
// countdown time in the message
|
||||
if (data.size() == 14 && !ProtocolManager::getInstance()->isServer())
|
||||
{
|
||||
uint32_t time_to_start = data.gui32(10);
|
||||
Log::debug("SynchronizationProtocol", "Request to start game in %d.", time_to_start);
|
||||
@ -134,10 +136,10 @@ void SynchronizationProtocol::asynchronousUpdate()
|
||||
{
|
||||
m_has_quit = true;
|
||||
Log::info("SynchronizationProtocol", "Countdown finished. Starting now.");
|
||||
m_listener->requestStart(new KartUpdateProtocol());
|
||||
m_listener->requestStart(new ControllerEventsProtocol());
|
||||
m_listener->requestStart(new GameEventsProtocol());
|
||||
m_listener->requestTerminate(this);
|
||||
(new KartUpdateProtocol())->requestStart();
|
||||
(new ControllerEventsProtocol())->requestStart();
|
||||
(new GameEventsProtocol())->requestStart();
|
||||
requestTerminate();
|
||||
return;
|
||||
}
|
||||
static int seconds = -1;
|
||||
@ -159,7 +161,8 @@ void SynchronizationProtocol::asynchronousUpdate()
|
||||
NetworkString ns(10);
|
||||
ns.ai8(i).addUInt32(peers[i]->getClientServerToken()).addUInt8(1).addUInt32(m_pings[i].size());
|
||||
// now add the countdown if necessary
|
||||
if (m_countdown_activated && m_listener->isServer())
|
||||
if (m_countdown_activated &&
|
||||
ProtocolManager::getInstance()->isServer())
|
||||
{
|
||||
ns.addUInt32((int)(m_countdown*1000.0));
|
||||
Log::debug("SynchronizationProtocol", "CNTActivated: Countdown value : %f", m_countdown);
|
||||
@ -167,7 +170,7 @@ void SynchronizationProtocol::asynchronousUpdate()
|
||||
Log::verbose("SynchronizationProtocol", "Added sequence number %u for peer %d", m_pings[i].size(), i);
|
||||
timer = current_time;
|
||||
m_pings[i].insert(std::pair<int,double>(m_pings_count[i], timer));
|
||||
m_listener->sendMessage(this, peers[i], ns, false);
|
||||
sendMessage(peers[i], ns, false);
|
||||
m_pings_count[i]++;
|
||||
}
|
||||
}
|
||||
|
@ -16,27 +16,67 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "network/server_network_manager.hpp"
|
||||
#include "network/server_console.hpp"
|
||||
|
||||
#include "main_loop.hpp"
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
#include "network/protocols/get_peer_address.hpp"
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
#include "network/protocols/hide_public_address.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "network/protocols/server_lobby_room_protocol.hpp"
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
#include "network/protocols/stop_server.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef XX
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
#include "network/protocols/get_peer_address.hpp"
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
#include "network/protocols/hide_public_address.hpp"
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
|
||||
#include <enet/enet.h>
|
||||
#include <pthread.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
void* waitInput2(void* data)
|
||||
ServerConsole::ServerConsole()
|
||||
{
|
||||
m_localhost = NULL;
|
||||
m_thread_keyboard = NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
ServerConsole::~ServerConsole()
|
||||
{
|
||||
if (m_thread_keyboard)
|
||||
pthread_cancel(*m_thread_keyboard);//, SIGKILL);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ServerConsole::run()
|
||||
{
|
||||
if (enet_initialize() != 0)
|
||||
{
|
||||
Log::error("ServerConsole", "Could not initialize enet.");
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info("ServerConsole", "Host initialized.");
|
||||
|
||||
// listen keyboard console input
|
||||
m_thread_keyboard = new pthread_t;
|
||||
pthread_create(m_thread_keyboard, NULL, mainLoop, this);
|
||||
|
||||
Log::info("ServerConsole", "Ready.");
|
||||
} // run
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void* ServerConsole::mainLoop(void* data)
|
||||
{
|
||||
ServerConsole *me = static_cast<ServerConsole*>(data);
|
||||
std::string str = "";
|
||||
bool stop = false;
|
||||
while(!stop)
|
||||
@ -48,7 +88,7 @@ void* waitInput2(void* data)
|
||||
}
|
||||
else if (str == "kickall")
|
||||
{
|
||||
ServerNetworkManager::getInstance()->kickAllPlayers();
|
||||
me->kickAllPlayers();
|
||||
}
|
||||
else if (str == "start")
|
||||
{
|
||||
@ -83,50 +123,20 @@ void* waitInput2(void* data)
|
||||
main_loop->abort();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
} // mainLoop
|
||||
|
||||
ServerNetworkManager::ServerNetworkManager()
|
||||
// ----------------------------------------------------------------------------
|
||||
void ServerConsole::kickAllPlayers()
|
||||
{
|
||||
m_localhost = NULL;
|
||||
m_thread_keyboard = NULL;
|
||||
}
|
||||
|
||||
ServerNetworkManager::~ServerNetworkManager()
|
||||
{
|
||||
if (m_thread_keyboard)
|
||||
pthread_cancel(*m_thread_keyboard);//, SIGKILL);
|
||||
}
|
||||
|
||||
void ServerNetworkManager::run()
|
||||
{
|
||||
if (enet_initialize() != 0)
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
{
|
||||
Log::error("ServerNetworkManager", "Could not initialize enet.");
|
||||
return;
|
||||
peers[i]->disconnect();
|
||||
}
|
||||
m_localhost = new STKHost();
|
||||
m_localhost->setupServer(STKHost::HOST_ANY, 7321, 16, 2, 0, 0);
|
||||
m_localhost->startListening();
|
||||
} // kickAllPlayers
|
||||
|
||||
Log::info("ServerNetworkManager", "Host initialized.");
|
||||
|
||||
// listen keyboard console input
|
||||
m_thread_keyboard = new pthread_t;
|
||||
pthread_create(m_thread_keyboard, NULL, waitInput2, NULL);
|
||||
|
||||
NetworkManager::run();
|
||||
Log::info("ServerNetworkManager", "Ready.");
|
||||
}
|
||||
|
||||
void ServerNetworkManager::kickAllPlayers()
|
||||
{
|
||||
for (unsigned int i = 0; i < m_peers.size(); i++)
|
||||
{
|
||||
m_peers[i]->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerNetworkManager::sendPacket(const NetworkString& data, bool reliable)
|
||||
// ----------------------------------------------------------------------------
|
||||
void ServerConsole::sendPacket(const NetworkString& data, bool reliable)
|
||||
{
|
||||
m_localhost->broadcastPacket(data, reliable);
|
||||
}
|
||||
} // sendPacket
|
58
src/network/server_console.hpp
Normal file
58
src/network/server_console.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013-2015 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef SERVER_CONSOLE_HPP
|
||||
#define SERVER_CONSOLE_HPP
|
||||
|
||||
#include "utils/types.hpp"
|
||||
|
||||
#include "pthread.h"
|
||||
|
||||
class NetworkString;
|
||||
class STKHost;
|
||||
|
||||
class ServerConsole
|
||||
{
|
||||
protected:
|
||||
|
||||
STKHost *m_localhost;
|
||||
|
||||
pthread_t* m_thread_keyboard;
|
||||
|
||||
uint8_t m_max_players;
|
||||
|
||||
static void* mainLoop(void* data);
|
||||
|
||||
public:
|
||||
ServerConsole();
|
||||
virtual ~ServerConsole();
|
||||
|
||||
virtual void run();
|
||||
|
||||
void setMaxPlayers(uint8_t count) { m_max_players = count; }
|
||||
uint8_t getMaxPlayers() { return m_max_players; }
|
||||
|
||||
void kickAllPlayers();
|
||||
|
||||
virtual void sendPacket(const NetworkString& data, bool reliable = true);
|
||||
|
||||
virtual bool isServer() { return true; }
|
||||
|
||||
}; // class ServerConsole
|
||||
|
||||
#endif // SERVER_CONSOLE_HPP
|
@ -1,57 +0,0 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013-2015 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
/*! \file server_network_manager.hpp
|
||||
*/
|
||||
|
||||
#ifndef SERVER_NETWORK_MANAGER_HPP
|
||||
#define SERVER_NETWORK_MANAGER_HPP
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
|
||||
|
||||
class ServerNetworkManager : public NetworkManager
|
||||
{
|
||||
friend class AbstractSingleton<NetworkManager>;
|
||||
public:
|
||||
static ServerNetworkManager* getInstance()
|
||||
{
|
||||
return AbstractSingleton<NetworkManager>::getInstance<ServerNetworkManager>();
|
||||
}
|
||||
|
||||
virtual void run();
|
||||
|
||||
void setMaxPlayers(uint8_t count) { m_max_players = count; }
|
||||
uint8_t getMaxPlayers() {return m_max_players;}
|
||||
|
||||
void kickAllPlayers();
|
||||
|
||||
virtual void sendPacket(const NetworkString& data, bool reliable = true);
|
||||
|
||||
virtual bool isServer() { return true; }
|
||||
|
||||
protected:
|
||||
ServerNetworkManager();
|
||||
virtual ~ServerNetworkManager();
|
||||
|
||||
pthread_t* m_thread_keyboard;
|
||||
uint8_t m_max_players;
|
||||
|
||||
};
|
||||
|
||||
#endif // SERVER_NETWORK_MANAGER_HPP
|
@ -22,6 +22,8 @@
|
||||
#include "io/file_manager.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocols/server_lobby_room_protocol.hpp"
|
||||
#include "network/server_console.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
@ -37,25 +39,9 @@
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
const char* inet_ntop(int af, const void* src, char* dst, int cnt)
|
||||
{
|
||||
struct sockaddr_in srcaddr;
|
||||
|
||||
memset(&srcaddr, 0, sizeof(struct sockaddr_in));
|
||||
memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr));
|
||||
|
||||
srcaddr.sin_family = af;
|
||||
if (WSAAddressToString((struct sockaddr*) &srcaddr,
|
||||
sizeof(struct sockaddr_in), 0, dst, (LPDWORD) &cnt) != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
Synchronised<FILE*> STKHost::m_log_file = NULL;
|
||||
STKHost *STKHost::m_stk_host = NULL;
|
||||
int STKHost::m_max_players = 0;
|
||||
bool STKHost::m_is_server = false;
|
||||
|
||||
// ============================================================================
|
||||
/** Constructor that just initialises this object (esp. opening the packet
|
||||
@ -63,18 +49,21 @@ Synchronised<FILE*> STKHost::m_log_file = NULL;
|
||||
*/
|
||||
STKHost::STKHost()
|
||||
{
|
||||
m_host = NULL;
|
||||
m_network = NULL;
|
||||
m_listening_thread = NULL;
|
||||
m_log_file.setAtomic(NULL);
|
||||
pthread_mutex_init(&m_exit_mutex, NULL);
|
||||
if (UserConfigParams::m_packets_log_filename.toString() != "")
|
||||
|
||||
Network::openLog();
|
||||
ProtocolManager::getInstance<ProtocolManager>();
|
||||
|
||||
if (m_is_server)
|
||||
{
|
||||
std::string s = file_manager
|
||||
->getUserConfigFile(UserConfigParams::m_packets_log_filename);
|
||||
m_log_file.setAtomic(fopen(s.c_str(), "w+"));
|
||||
ServerConsole *sc = new ServerConsole();
|
||||
sc->run();
|
||||
setupServer(STKHost::HOST_ANY, 7321, 16, 2, 0, 0);
|
||||
startListening();
|
||||
ProtocolManager::getInstance()->requestStart(new ServerLobbyRoomProtocol());
|
||||
}
|
||||
if (!m_log_file.getData())
|
||||
Log::warn("STKHost", "Network packets won't be logged: no file.");
|
||||
} // STKHost
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -83,46 +72,11 @@ STKHost::STKHost()
|
||||
*/
|
||||
STKHost::~STKHost()
|
||||
{
|
||||
Network::closeLog();
|
||||
stopListening();
|
||||
if (m_log_file.getData())
|
||||
{
|
||||
m_log_file.lock();
|
||||
fclose(m_log_file.getData());
|
||||
Log::warn("STKHost", "Packet logging file has been closed.");
|
||||
m_log_file.getData() = NULL;
|
||||
m_log_file.unlock();
|
||||
}
|
||||
if (m_host)
|
||||
{
|
||||
enet_host_destroy(m_host);
|
||||
}
|
||||
delete m_network;
|
||||
} // ~STKHost
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Log packets into a file
|
||||
* \param ns : The data in the packet
|
||||
* \param incoming : True if the packet comes from a peer.
|
||||
* False if it's sent to a peer.
|
||||
*/
|
||||
void STKHost::logPacket(const NetworkString &ns, bool incoming)
|
||||
{
|
||||
if (m_log_file.getData() == NULL) // read only access, no need to lock
|
||||
return;
|
||||
|
||||
const char *arrow = incoming ? "<--" : "-->";
|
||||
|
||||
m_log_file.lock();
|
||||
fprintf(m_log_file.getData(), "[%d\t] %s ",
|
||||
(int)(StkTime::getRealTime()), arrow);
|
||||
|
||||
for (int i = 0; i < ns.size(); i++)
|
||||
{
|
||||
fprintf(m_log_file.getData(), "%d.", ns[i]);
|
||||
}
|
||||
fprintf(m_log_file.getData(), "\n");
|
||||
m_log_file.unlock();
|
||||
} // logPacket
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Starts the listening of events from ENet.
|
||||
* Starts a thread for receiveData that updates it as often as possible.
|
||||
@ -174,7 +128,7 @@ void* STKHost::mainLoop(void* self)
|
||||
{
|
||||
ENetEvent event;
|
||||
STKHost* myself = (STKHost*)(self);
|
||||
ENetHost* host = myself->m_host;
|
||||
ENetHost* host = myself->m_network->getENetHost();
|
||||
while (!myself->mustStopListening())
|
||||
{
|
||||
while (enet_host_service(host, &event, 20) != 0)
|
||||
@ -185,7 +139,7 @@ void* STKHost::mainLoop(void* self)
|
||||
// Create an STKEvent with the event data
|
||||
Event* stk_event = new Event(&event);
|
||||
if (stk_event->getType() == EVENT_TYPE_MESSAGE)
|
||||
logPacket(stk_event->data(), true);
|
||||
Network::logPacket(stk_event->data(), true);
|
||||
|
||||
// The event is forwarded to the NetworkManger and from there
|
||||
// there to the ProtocolManager. The ProtocolManager is
|
||||
@ -202,7 +156,7 @@ void* STKHost::mainLoop(void* self)
|
||||
} // mainLoop
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Setups this host as a server.
|
||||
/** \brief Setup this host as a server.
|
||||
* \param address : The IPv4 address of incoming connections.
|
||||
* \param port : The port on which the server listens.
|
||||
* \param peer_count : The maximum number of peers.
|
||||
@ -218,16 +172,10 @@ void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count,
|
||||
addr->host = address;
|
||||
addr->port = port;
|
||||
|
||||
#ifdef WIN32/*
|
||||
addr->host = 0;
|
||||
addr->host += ((unsigned int)(192)<<0); // 192.168.0.11
|
||||
addr->host += ((unsigned int)(168)<<8); // 192.168.0.11
|
||||
addr->host += ((unsigned int)(11)<<24); // 192.168.0.11*/
|
||||
#endif
|
||||
|
||||
m_host = enet_host_create(addr, peer_count, channel_limit,
|
||||
max_incoming_bandwidth, max_outgoing_bandwidth);
|
||||
if (!m_host)
|
||||
m_network= new Network(peer_count, channel_limit,
|
||||
max_incoming_bandwidth,
|
||||
max_outgoing_bandwidth, addr);
|
||||
if (!m_network)
|
||||
{
|
||||
Log::fatal("STKHost", "An error occurred while trying to create an ENet"
|
||||
" server host.");
|
||||
@ -247,159 +195,16 @@ void STKHost::setupClient(int peer_count, int channel_limit,
|
||||
uint32_t max_incoming_bandwidth,
|
||||
uint32_t max_outgoing_bandwidth)
|
||||
{
|
||||
m_host = enet_host_create(NULL, peer_count, channel_limit,
|
||||
max_incoming_bandwidth, max_outgoing_bandwidth);
|
||||
if (!m_host)
|
||||
m_network = new Network(peer_count, channel_limit,
|
||||
max_incoming_bandwidth,
|
||||
max_outgoing_bandwidth, NULL);
|
||||
if (!m_network)
|
||||
{
|
||||
Log::fatal ("STKHost", "An error occurred while trying to create an "
|
||||
"ENet client host.");
|
||||
Log::fatal ("STKHost", "An error occurred while trying to create "
|
||||
"an ENet client host.");
|
||||
}
|
||||
} // setupClient
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Sends a packet whithout ENet adding its headers.
|
||||
* This function is used in particular to achieve the STUN protocol.
|
||||
* \param data : Data to send.
|
||||
* \param length : Length of the sent data.
|
||||
* \param dst : Destination of the packet.
|
||||
*/
|
||||
void STKHost::sendRawPacket(uint8_t* data, int length,
|
||||
const TransportAddress& dst)
|
||||
{
|
||||
struct sockaddr_in to;
|
||||
int to_len = sizeof(to);
|
||||
memset(&to,0,to_len);
|
||||
|
||||
to.sin_family = AF_INET;
|
||||
to.sin_port = htons(dst.getPort());
|
||||
to.sin_addr.s_addr = htonl(dst.getIP());
|
||||
|
||||
sendto(m_host->socket, (char*)data, length, 0,(sockaddr*)&to, to_len);
|
||||
Log::verbose("STKHost", "Raw packet sent to %s", dst.toString().c_str());
|
||||
STKHost::logPacket(NetworkString(std::string((char*)(data), length)),
|
||||
false);
|
||||
} // sendRawPacket
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Receives a packet directly from the network interface.
|
||||
* Receive a packet whithout ENet processing it and returns the
|
||||
* sender's ip address and port in the TransportAddress structure.
|
||||
* \param sender : Stores the transport address of the sender of the
|
||||
* received packet.
|
||||
* \return A string containing the data of the received packet.
|
||||
*/
|
||||
uint8_t* STKHost::receiveRawPacket(TransportAddress* sender)
|
||||
{
|
||||
const int LEN = 2048;
|
||||
// max size needed normally (only used for stun)
|
||||
uint8_t* buffer = new uint8_t[LEN];
|
||||
memset(buffer, 0, LEN);
|
||||
|
||||
socklen_t from_len;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
from_len = sizeof(addr);
|
||||
int len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||
(struct sockaddr*)(&addr), &from_len );
|
||||
|
||||
int i = 0;
|
||||
// wait to receive the message because enet sockets are non-blocking
|
||||
while(len == -1) // nothing received
|
||||
{
|
||||
StkTime::sleep(1); // wait 1 millisecond between two checks
|
||||
i++;
|
||||
len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||
(struct sockaddr*)(&addr), &from_len );
|
||||
}
|
||||
if (len == SOCKET_ERROR)
|
||||
{
|
||||
Log::error("STKHost",
|
||||
"Problem with the socket. Please contact the dev team.");
|
||||
}
|
||||
// we received the data
|
||||
sender->setIP( ntohl((uint32_t)(addr.sin_addr.s_addr)) );
|
||||
sender->setPort( ntohs(addr.sin_port) );
|
||||
|
||||
if (addr.sin_family == AF_INET)
|
||||
{
|
||||
Log::info("STKHost", "IPv4 Address of the sender was %s",
|
||||
sender->toString().c_str());
|
||||
}
|
||||
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
|
||||
return buffer;
|
||||
} // receiveRawPacket(TransportAddress* sender)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Receives a packet directly from the network interface and
|
||||
* filter its address.
|
||||
* Receive a packet whithout ENet processing it. Checks that the
|
||||
* sender of the packet is the one that corresponds to the sender
|
||||
* parameter. Does not check the port right now.
|
||||
* \param sender : Transport address of the original sender of the
|
||||
* wanted packet.
|
||||
* \param max_tries : Number of times we try to read data from the
|
||||
* socket. This is aproximately the time we wait in
|
||||
* milliseconds. -1 means eternal tries.
|
||||
* \return A string containing the data of the received packet
|
||||
* matching the sender's ip address.
|
||||
*/
|
||||
uint8_t* STKHost::receiveRawPacket(const TransportAddress& sender,
|
||||
int max_tries)
|
||||
{
|
||||
const int LEN = 2048;
|
||||
uint8_t* buffer = new uint8_t[LEN];
|
||||
memset(buffer, 0, LEN);
|
||||
|
||||
socklen_t from_len;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
from_len = sizeof(addr);
|
||||
int len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||
(struct sockaddr*)(&addr), &from_len );
|
||||
|
||||
int count = 0;
|
||||
// wait to receive the message because enet sockets are non-blocking
|
||||
while(len < 0 || addr.sin_addr.s_addr == sender.getIP())
|
||||
{
|
||||
count++;
|
||||
if (len>=0)
|
||||
{
|
||||
Log::info("STKHost", "Message received but the ip address didn't "
|
||||
"match the expected one.");
|
||||
}
|
||||
len = recvfrom(m_host->socket, (char*)buffer, LEN, 0,
|
||||
(struct sockaddr*)(&addr), &from_len);
|
||||
StkTime::sleep(1); // wait 1 millisecond between two checks
|
||||
if (count >= max_tries && max_tries != -1)
|
||||
{
|
||||
TransportAddress a(m_host->address);
|
||||
Log::verbose("STKHost", "No answer from the server on %s",
|
||||
a.toString().c_str());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (addr.sin_family == AF_INET)
|
||||
{
|
||||
TransportAddress a(ntohl(addr.sin_addr.s_addr));
|
||||
Log::info("STKHost", "IPv4 Address of the sender was %s",
|
||||
a.toString(false).c_str());
|
||||
}
|
||||
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
|
||||
return buffer;
|
||||
} // receiveRawPacket(const TransportAddress& sender, int max_tries)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Broadcasts a packet to all peers.
|
||||
* \param data : Data to send.
|
||||
*/
|
||||
void STKHost::broadcastPacket(const NetworkString& data, bool reliable)
|
||||
{
|
||||
ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1,
|
||||
reliable ? ENET_PACKET_FLAG_RELIABLE
|
||||
: ENET_PACKET_FLAG_UNSEQUENCED);
|
||||
enet_host_broadcast(m_host, 0, packet);
|
||||
STKHost::logPacket(data, false);
|
||||
} // broadcastPacket
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Tells if a peer is known.
|
||||
@ -407,10 +212,11 @@ void STKHost::broadcastPacket(const NetworkString& data, bool reliable)
|
||||
*/
|
||||
bool STKHost::peerExists(const TransportAddress& peer)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_host->peerCount; i++)
|
||||
ENetHost *host = m_network->getENetHost();
|
||||
for (unsigned int i = 0; i < host->peerCount ; i++)
|
||||
{
|
||||
if (m_host->peers[i].address.host == ntohl(peer.getIP()) &&
|
||||
m_host->peers[i].address.port == peer.getPort() )
|
||||
if (host->peers[i].address.host == ntohl(peer.getIP()) &&
|
||||
host->peers[i].address.port == peer.getPort() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -424,10 +230,11 @@ bool STKHost::peerExists(const TransportAddress& peer)
|
||||
*/
|
||||
bool STKHost::isConnectedTo(const TransportAddress& peer)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_host->peerCount; i++)
|
||||
ENetHost *host = m_network->getENetHost();
|
||||
for (unsigned int i = 0; i < host->peerCount; i++)
|
||||
{
|
||||
if (peer == m_host->peers[i].address &&
|
||||
m_host->peers[i].state == ENET_PEER_STATE_CONNECTED)
|
||||
if (peer == host->peers[i].address &&
|
||||
host->peers[i].state == ENET_PEER_STATE_CONNECTED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -440,7 +247,8 @@ uint16_t STKHost::getPort() const
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
if (getsockname(m_host->socket, (struct sockaddr *)&sin, &len) == -1)
|
||||
ENetHost *host = m_network->getENetHost();
|
||||
if (getsockname(host->socket, (struct sockaddr *)&sin, &len) == -1)
|
||||
Log::error("STKHost", "Error while using getsockname().");
|
||||
else
|
||||
return ntohs(sin.sin_port);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#ifndef STK_HOST_HPP
|
||||
#define STK_HOST_HPP
|
||||
|
||||
#include "network/network.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/types.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
@ -46,64 +47,125 @@
|
||||
*/
|
||||
class STKHost
|
||||
{
|
||||
public:
|
||||
/** \brief Defines three host types for the server.
|
||||
* These values tells the host where he will accept connections from.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
HOST_ANY = 0, //!< Any host.
|
||||
HOST_BROADCAST = 0xFFFFFFFF, //!< Defines the broadcast address.
|
||||
PORT_ANY = 0 //!< Any port.
|
||||
};
|
||||
|
||||
|
||||
friend class STKPeer; // allow direct enet modifications in implementations
|
||||
|
||||
private:
|
||||
/** Singleton pointer to the instance. */
|
||||
static STKHost* m_stk_host;
|
||||
|
||||
/** True if this host is a server, false otherwise. */
|
||||
static bool m_is_server;
|
||||
|
||||
/** ENet host interfacing sockets. */
|
||||
ENetHost* m_host;
|
||||
Network* m_network;
|
||||
|
||||
/** Id of thread listening to enet events. */
|
||||
pthread_t* m_listening_thread;
|
||||
pthread_t* m_listening_thread;
|
||||
|
||||
/** Mutex used to stop this thread. */
|
||||
pthread_mutex_t m_exit_mutex;
|
||||
|
||||
//** Where to log packets. If NULL for FILE* logging is disabled. */
|
||||
static Synchronised<FILE*> m_log_file;
|
||||
/** Maximum number of players on the server. */
|
||||
static int m_max_players;
|
||||
|
||||
public:
|
||||
/*! \enum HOST_TYPE
|
||||
* \brief Defines three host types for the server.
|
||||
* These values tells the host where he will accept connections from.
|
||||
*/
|
||||
enum HOST_TYPE
|
||||
{
|
||||
HOST_ANY = 0, //!< Any host.
|
||||
HOST_BROADCAST = 0xFFFFFFFF, //!< Defines the broadcast address.
|
||||
PORT_ANY = 0 //!< Any port.
|
||||
};
|
||||
STKHost();
|
||||
virtual ~STKHost();
|
||||
|
||||
/*! \brief Constructor */
|
||||
STKHost();
|
||||
/*! \brief Destructor */
|
||||
virtual ~STKHost();
|
||||
|
||||
static void logPacket(const NetworkString &ns, bool incoming);
|
||||
static void* mainLoop(void* self);
|
||||
public:
|
||||
|
||||
void setupServer(uint32_t address, uint16_t port,
|
||||
int peer_count, int channel_limit,
|
||||
uint32_t max_incoming_bandwidth,
|
||||
uint32_t max_outgoing_bandwidth);
|
||||
void setupClient(int peer_count, int channel_limit,
|
||||
uint32_t max_incoming_bandwidth,
|
||||
uint32_t max_outgoing_bandwidth);
|
||||
void startListening();
|
||||
void stopListening();
|
||||
void sendRawPacket(uint8_t* data, int length,
|
||||
const TransportAddress& dst);
|
||||
uint8_t* receiveRawPacket(TransportAddress* sender);
|
||||
uint8_t* receiveRawPacket(const TransportAddress& sender,
|
||||
int max_tries = -1);
|
||||
void broadcastPacket(const NetworkString& data,
|
||||
bool reliable = true);
|
||||
bool peerExists(const TransportAddress& peer_address);
|
||||
bool isConnectedTo(const TransportAddress& peer_address);
|
||||
int mustStopListening();
|
||||
uint16_t getPort() const;
|
||||
// --------------------------------------------------------------------
|
||||
uint32_t getAddress() const { return m_host->address.host; }
|
||||
/** Creates the singleton. */
|
||||
static void create(bool is_server)
|
||||
{
|
||||
m_is_server = is_server;
|
||||
assert(m_stk_host == NULL);
|
||||
m_stk_host = new STKHost();
|
||||
} // create
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the instance of STKHost. */
|
||||
static STKHost *get()
|
||||
{
|
||||
assert(m_stk_host != NULL);
|
||||
return m_stk_host;
|
||||
} // get
|
||||
// ------------------------------------------------------------------------
|
||||
static void destroy()
|
||||
{
|
||||
assert(m_stk_host != NULL);
|
||||
delete m_stk_host;
|
||||
m_stk_host = NULL;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
};
|
||||
static void* mainLoop(void* self);
|
||||
|
||||
void setupServer(uint32_t address, uint16_t port,
|
||||
int peer_count, int channel_limit,
|
||||
uint32_t max_incoming_bandwidth,
|
||||
uint32_t max_outgoing_bandwidth);
|
||||
void setupClient(int peer_count, int channel_limit,
|
||||
uint32_t max_incoming_bandwidth,
|
||||
uint32_t max_outgoing_bandwidth);
|
||||
void startListening();
|
||||
void stopListening();
|
||||
uint8_t* receiveRawPacket(const TransportAddress& sender,
|
||||
int max_tries = -1);
|
||||
bool peerExists(const TransportAddress& peer_address);
|
||||
bool isConnectedTo(const TransportAddress& peer_address);
|
||||
int mustStopListening();
|
||||
uint16_t getPort() const;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
ENetPeer* connectTo(const TransportAddress &address)
|
||||
{
|
||||
return m_network->connectTo(address);
|
||||
} // connectTo
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
uint8_t* receiveRawPacket(TransportAddress* sender)
|
||||
{
|
||||
return m_network->receiveRawPacket(sender);
|
||||
} // receiveRawPacket
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void broadcastPacket(const NetworkString& data,
|
||||
bool reliable = true)
|
||||
{
|
||||
m_network->broadcastPacket(data, reliable);
|
||||
} // broadcastPacket
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
void sendRawPacket(uint8_t* data, int length,
|
||||
const TransportAddress& dst)
|
||||
{
|
||||
m_network->sendRawPacket(data, length, dst);
|
||||
} // sendRawPacket
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the IP address of this host. */
|
||||
uint32_t getAddress() const
|
||||
{
|
||||
return m_network->getENetHost()->address.host;
|
||||
} // getAddress
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets the maximum number of players for this server. */
|
||||
static void setMaxPlayers(int n) { m_max_players = n; }
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the maximum number of players for this server. */
|
||||
static int getMaxPlayers() { return m_max_players; }
|
||||
|
||||
}; // class STKHost
|
||||
|
||||
#endif // STK_HOST_HPP
|
||||
|
@ -50,12 +50,11 @@ STKPeer::~STKPeer()
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Connect to the specified host.
|
||||
*/
|
||||
bool STKPeer::connectToHost(STKHost* localhost, const TransportAddress &host,
|
||||
bool STKPeer::connectToHost(STKHost* localhost, const TransportAddress &address,
|
||||
uint32_t channel_count, uint32_t data)
|
||||
{
|
||||
const ENetAddress address = host.toEnetAddress();
|
||||
ENetPeer* peer = localhost->connectTo(address);
|
||||
|
||||
ENetPeer* peer = enet_host_connect(localhost->m_host, &address, 2, 0);
|
||||
if (peer == NULL)
|
||||
{
|
||||
Log::error("STKPeer", "Could not try to connect to server.\n");
|
||||
|
@ -19,8 +19,8 @@
|
||||
/*! \file types.hpp
|
||||
* \brief Declares the general types that are used by the network.
|
||||
*/
|
||||
#ifndef TYPES_HPP
|
||||
#define TYPES_HPP
|
||||
#ifndef HEADER_NETWORK_TYPES_HPP
|
||||
#define HEADER_NETWORK_TYPES_HPP
|
||||
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user