Moved handling of peers from NetworkManager to STKHost.

This commit is contained in:
hiker 2015-10-26 08:33:07 +11:00
parent f610573295
commit 4c0a195fdd
16 changed files with 182 additions and 189 deletions

View File

@ -1526,7 +1526,7 @@ int main(int argc, char *argv[] )
// so we don't crash later when StateManager tries to access input devices.
StateManager::get()->resetActivePlayers();
if(input_manager) delete input_manager; // if early crash avoid delete NULL
NetworkManager::getInstance()->abort();
STKHost::get()->abort();
cleanSuperTuxKart();

View File

@ -99,12 +99,12 @@ void* waitInput(void* data)
// If STK shuts down, but should receive an input after the network
// manager was deleted, the getInstance call will return NULL.
else if (NetworkManager::getInstance() &&
NetworkManager::getInstance()->getPeers().size() > 0)
STKHost::get()->getPeerCount() > 0)
{
NetworkString msg(1+str.size());
msg.ai8(0);
msg += str;
NetworkManager::getInstance()->getPeers()[0]->sendPacket(msg);
STKHost::get()->getPeers()[0]->sendPacket(msg);
}
}
@ -166,7 +166,7 @@ void ClientNetworkManager::run()
void ClientNetworkManager::reset()
{
NetworkManager::reset();
STKHost::get()->reset();
m_connected = false;
STKHost::create(/*is_server*/false);
@ -177,12 +177,12 @@ void ClientNetworkManager::reset()
void ClientNetworkManager::sendPacket(const NetworkString& data, bool reliable)
{
if (m_peers.size() > 1)
if (STKHost::get()->getPeerCount() > 1)
Log::warn("ClientNetworkManager", "Ambiguous send of data.\n");
m_peers[0]->sendPacket(data, reliable);
STKHost::get()->getPeers()[0]->sendPacket(data, reliable);
}
STKPeer* ClientNetworkManager::getPeer()
{
return m_peers[0];
return STKHost::get()->getPeers()[0];
}

View File

@ -58,7 +58,7 @@ Event::Event(ENetEvent* event)
}
m_packet = NULL;
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
m_peer = NULL;
for (unsigned int i = 0; i < peers.size(); i++)
{
@ -70,6 +70,7 @@ Event::Event(ENetEvent* event)
return;
}
}
if (m_peer == NULL) // peer does not exist, create him
{
STKPeer* new_peer = new STKPeer();

View File

@ -39,11 +39,6 @@ NetworkManager::~NetworkManager()
ProtocolManager::kill();
STKHost::destroy();
while(!m_peers.empty())
{
delete m_peers.back();
m_peers.pop_back();
}
} // ~Networkmanager
//----------------------------------------------------------------------------
@ -53,34 +48,6 @@ void NetworkManager::run()
{
} // run
//-----------------------------------------------------------------------------
/** \brief Function to reset the Network Manager.
* This function resets the peers and the listening host.
*/
void NetworkManager::reset()
{
STKHost::destroy();
while(!m_peers.empty())
{
delete m_peers.back();
m_peers.pop_back();
}
} // reset
//-----------------------------------------------------------------------------
/** \brief Function that aborts the NetworkManager.
* This function will stop the listening, delete the host and stop
* threads that are related to networking.
*/
void NetworkManager::abort()
{
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();
ProtocolManager::getInstance()->abort();
} // abort
//-----------------------------------------------------------------------------
/** \brief Try to establish a connection to a given transport address.
* \param peer : The transport address which you want to connect to.
@ -94,43 +61,6 @@ bool NetworkManager::connect(const TransportAddress& address)
return STKPeer::connectToHost(STKHost::get(), address, 2, 0);
} // connect
//-----------------------------------------------------------------------------
/** Is called from STKHost when an event (i.e. a package) is received. If the
* event indicates a new connection, the peer is added to the list of peers.
* It logs the package, and propagates the event to the ProtocollManager,
* which in turn will notify individual protocols.
* \param event Pointer to the event to propagate.
*/
void NetworkManager::propagateEvent(Event* event)
{
Log::verbose("NetworkManager", "EVENT received of type %d",
(int)(event->getType()));
STKPeer* peer = event->getPeer();
if (event->getType() == EVENT_TYPE_CONNECTED)
{
Log::info("NetworkManager", "A client has just connected. There are "
"now %lu peers.", m_peers.size() + 1);
Log::debug("NetworkManager", "Addresses are : %lx, %lx",
event->getPeer(), peer);
// create the new peer:
m_peers.push_back(peer);
}
if (event->getType() == EVENT_TYPE_MESSAGE)
{
uint32_t addr = peer->getAddress();
Log::verbose("NetworkManager",
"Message, Sender : %i.%i.%i.%i, message = \"%s\"",
((addr>>24)&0xff),
((addr>>16)&0xff),
((addr>>8)&0xff),
(addr & 0xff), event->data().std_string().c_str());
}
// notify for the event now.
ProtocolManager::getInstance()->propagateEvent(event);
} // propagateEvent
//-----------------------------------------------------------------------------
void NetworkManager::sendPacket(STKPeer* peer, const NetworkString& data,
@ -140,74 +70,6 @@ void NetworkManager::sendPacket(STKPeer* peer, const NetworkString& data,
peer->sendPacket(data, reliable);
} // sendPacket
//-----------------------------------------------------------------------------
void NetworkManager::sendPacketExcept(STKPeer* peer, const NetworkString& data,
bool reliable)
{
for (unsigned int i = 0; i < m_peers.size(); i++)
{
STKPeer* p = m_peers[i];
if (!p->isSamePeer(peer))
{
p->sendPacket(data, reliable);
}
}
} // sendPacketExcept
//-----------------------------------------------------------------------------
/** Called when you leave a server.
*/
void NetworkManager::disconnected()
{
// remove all peers
for (unsigned int i = 0; i < m_peers.size(); i++)
{
delete m_peers[i];
m_peers[i] = NULL;
}
m_peers.clear();
} // disconnected
//-----------------------------------------------------------------------------
void NetworkManager::removePeer(STKPeer* peer)
{
if (!peer || !peer->exists()) // peer does not exist (already removed)
return;
Log::debug("NetworkManager", "Disconnected host: %i.%i.%i.%i:%i",
peer->getAddress()>>24&0xff,
peer->getAddress()>>16&0xff,
peer->getAddress()>>8&0xff,
peer->getAddress()&0xff,
peer->getPort());
// remove the peer:
bool removed = false;
for (unsigned int i = 0; i < m_peers.size(); i++)
{
if (m_peers[i]->isSamePeer(peer) && !removed) // remove only one
{
delete m_peers[i];
m_peers.erase(m_peers.begin()+i, m_peers.begin()+i+1);
Log::verbose("NetworkManager",
"The peer has been removed from the Network Manager.");
removed = true;
}
else if (m_peers[i]->isSamePeer(peer))
{
Log::fatal("NetworkManager",
"Multiple peers match the disconnected one.");
}
}
if (!removed)
Log::warn("NetworkManager", "The peer that has been disconnected was "
"not registered by the Network Manager.");
Log::info("NetworkManager",
"Somebody is now disconnected. There are now %lu peers.",
m_peers.size());
} // removePeer
//-----------------------------------------------------------------------------

View File

@ -51,8 +51,6 @@ protected:
NetworkManager();
virtual ~NetworkManager();
/** The list of peers connected to this instance. */
std::vector<STKPeer*> m_peers;
private:
@ -62,25 +60,17 @@ private:
friend class AbstractSingleton<NetworkManager>;
public:
virtual void run();
virtual void reset();
virtual void abort();
virtual bool connect(const TransportAddress& peer);
virtual void propagateEvent(Event* event);
virtual void sendPacket(const NetworkString& data,
bool reliable = true) = 0;
virtual void sendPacket(STKPeer* peer,
const NetworkString& data,
bool reliable = true);
virtual void sendPacketExcept(STKPeer* peer,
const NetworkString& data,
bool reliable = true);
// Game related functions
virtual void disconnected();
virtual bool isServer() = 0;
// raw data management
void removePeer(STKPeer* peer);
// getters
// --------------------------------------------------------------------
@ -91,10 +81,6 @@ public:
// --------------------------------------------------------------------
inline bool isClient() { return !isServer(); }
// --------------------------------------------------------------------
std::vector<STKPeer*> getPeers() { return m_peers; }
// --------------------------------------------------------------------
unsigned int getPeerCount() { return (int)m_peers.size(); }
}; // class NetworkManager

View File

@ -100,7 +100,7 @@ void Protocol::requestTerminate()
void Protocol::sendMessageToPeersChangingToken(NetworkString prefix,
NetworkString message)
{
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
for (unsigned int i = 0; i < peers.size(); i++)
{
prefix.ai8(4).ai32(peers[i]->getClientServerToken());

View File

@ -194,10 +194,10 @@ void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer,
const NetworkString& message,
bool reliable)
{
NetworkString newMessage(1+message.size());
newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type
newMessage += message;
NetworkManager::getInstance()->sendPacketExcept(peer, newMessage, reliable);
NetworkString new_message(1+message.size());
new_message.ai8(sender->getProtocolType()); // add one byte to add protocol type
new_message += message;
STKHost::get()->sendPacketExcept(peer, new_message, reliable);
} // sendMessageExcept
// ----------------------------------------------------------------------------

View File

@ -206,13 +206,13 @@ bool ClientLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
} // connection
else if (event->getType() == EVENT_TYPE_DISCONNECTED) // means we left essentially
{
NetworkManager::getInstance()->removePeer(m_server);
STKHost::get()->removePeer(m_server);
m_server = NULL;
NetworkManager::getInstance()->disconnected();
STKHost::get()->deleteAllPeers();
ProtocolManager::getInstance()->requestTerminate(this);
NetworkManager::getInstance()->reset();
STKHost::get()->reset();
// probably the same as m_server
NetworkManager::getInstance()->removePeer(event->getPeer());
STKHost::get()->removePeer(event->getPeer());
return true;
} // disconnection
return false;
@ -543,7 +543,7 @@ void ClientLobbyRoomProtocol::startGame(Event* event)
return;
}
uint8_t token = data.gui32(1);
if (token == NetworkManager::getInstance()->getPeers()[0]->getClientServerToken())
if (token == STKHost::get()->getPeers()[0]->getClientServerToken())
{
m_state = PLAYING;
ProtocolManager::getInstance()->requestStart(new StartGameProtocol(m_setup));
@ -576,7 +576,7 @@ void ClientLobbyRoomProtocol::startSelection(Event* event)
return;
}
uint8_t token = data.gui32(1);
if (token == NetworkManager::getInstance()->getPeers()[0]->getClientServerToken())
if (token == STKHost::get()->getPeers()[0]->getClientServerToken())
{
m_state = KART_SELECTION;
Log::info("ClientLobbyRoomProtocol", "Kart selection starts now");

View File

@ -28,7 +28,7 @@ void ControllerEventsProtocol::setup()
{
m_self_controller_index = 0;
std::vector<AbstractKart*> karts = World::getWorld()->getKarts();
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
for (unsigned int i = 0; i < karts.size(); i++)
{
if (karts[i]->getIdent() == NetworkWorld::getInstance()->m_self_kart)

View File

@ -79,7 +79,7 @@ void GameEventsProtocol::collectedItem(Item* item, AbstractKart* kart)
assert(setup);
const NetworkPlayerProfile* player_profile = setup->getProfile(kart->getIdent()); // use kart name
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
for (unsigned int i = 0; i < peers.size(); i++)
{
NetworkString ns(11);

View File

@ -151,7 +151,7 @@ void ServerLobbyRoomProtocol::update()
void ServerLobbyRoomProtocol::startGame()
{
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
for (unsigned int i = 0; i < peers.size(); i++)
{
NetworkString ns(6);
@ -167,7 +167,7 @@ void ServerLobbyRoomProtocol::startGame()
void ServerLobbyRoomProtocol::startSelection()
{
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
for (unsigned int i = 0; i < peers.size(); i++)
{
NetworkString ns(6);
@ -260,7 +260,7 @@ void ServerLobbyRoomProtocol::checkRaceFinished()
}
}
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
NetworkString queue(karts_results.size()*2);
for (unsigned int i = 0; i < karts_results.size(); i++)
@ -323,7 +323,7 @@ void ServerLobbyRoomProtocol::kartDisconnected(Event* event)
Log::info("ServerLobbyRoomProtocol", "Player disconnected : id %d",
peer->getPlayerProfile()->race_id);
m_setup->removePlayer(peer->getPlayerProfile()->race_id);
NetworkManager::getInstance()->removePeer(peer);
STKHost::get()->removePeer(peer);
}
else
Log::info("ServerLobbyRoomProtocol", "The DC peer wasn't registered.");

View File

@ -207,9 +207,9 @@ void StartGameProtocol::ready() // on clients, means the loading is finished
{
if (!ProtocolManager::getInstance()->isServer()) // if we're a client
{
assert(NetworkManager::getInstance()->getPeerCount() == 1);
assert(STKHost::get()->getPeerCount() == 1);
NetworkString ns(5);
ns.ai32(NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()).ai8(1);
ns.ai32(STKHost::get()->getPeers()[0]->getClientServerToken()).ai8(1);
Log::info("StartGameProtocol", "Player ready, notifying server.");
sendMessage(ns, true);
m_state = READY;

View File

@ -11,7 +11,7 @@
SynchronizationProtocol::SynchronizationProtocol() : Protocol(NULL, PROTOCOL_SYNCHRONIZATION)
{
unsigned int size = NetworkManager::getInstance()->getPeerCount();
unsigned int size = STKHost::get()->getPeerCount();
m_pings.resize(size, std::map<uint32_t,double>());
m_pings_count.resize(size);
for (unsigned int i = 0; i < size; i++)
@ -47,7 +47,7 @@ bool SynchronizationProtocol::notifyEventAsynchronous(Event* event)
uint32_t request = data.gui8(5);
uint32_t sequence = data.gui32(6);
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
assert(peers.size() > 0);
if (ProtocolManager::getInstance()->isServer())
@ -155,7 +155,7 @@ void SynchronizationProtocol::asynchronousUpdate()
}
if (current_time > timer+0.1)
{
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
for (unsigned int i = 0; i < peers.size(); i++)
{
NetworkString ns(10);

View File

@ -128,7 +128,7 @@ void* ServerConsole::mainLoop(void* data)
// ----------------------------------------------------------------------------
void ServerConsole::kickAllPlayers()
{
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
for (unsigned int i = 0; i < peers.size(); i++)
{
peers[i]->disconnect();

View File

@ -83,12 +83,21 @@ STKHost::~STKHost()
delete m_game_setup;
m_game_setup = NULL;
// Delete all connected peers
while (!m_peers.empty())
{
delete m_peers.back();
m_peers.pop_back();
}
Network::closeLog();
stopListening();
delete m_network;
} // ~STKHost
//-----------------------------------------------------------------------------
/** Stores the public address of this host.
*/
void STKHost::setPublicAddress(const TransportAddress& addr)
{
m_public_address.lock();
@ -108,6 +117,44 @@ GameSetup* STKHost::setupNewGame()
return m_game_setup;
} // setupNewGame
//-----------------------------------------------------------------------------
/** \brief Function to reset the host - called in case that a client
* is disconnected from a server.
* This function resets the peers and the listening host.
*/
void STKHost::reset()
{
deleteAllPeers();
destroy();
} // reset
//-----------------------------------------------------------------------------
/** Called when you leave a server.
*/
void STKHost::deleteAllPeers()
{
// remove all peers
for (unsigned int i = 0; i < m_peers.size(); i++)
{
delete m_peers[i];
m_peers[i] = NULL;
}
m_peers.clear();
} // deleteAllPeers
// ----------------------------------------------------------------------------
/** Called when STK exits. It stops the listening thread and the
* ProtocolManager.
*/
void STKHost::abort()
{
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();
ProtocolManager::getInstance()->abort();
} // abort
// ----------------------------------------------------------------------------
/** \brief Starts the listening of events from ENet.
* Starts a thread for receiveData that updates it as often as possible.
@ -172,10 +219,30 @@ void* STKHost::mainLoop(void* self)
if (stk_event->getType() == EVENT_TYPE_MESSAGE)
Network::logPacket(stk_event->data(), true);
// The event is forwarded to the NetworkManger and from there
// there to the ProtocolManager. The ProtocolManager is
// responsible for freeing the memory.
NetworkManager::getInstance()->propagateEvent(stk_event);
Log::verbose("STKHost", "Event of type %d received",
(int)(stk_event->getType()));
STKPeer* peer = stk_event->getPeer();
if (stk_event->getType() == EVENT_TYPE_CONNECTED)
{
// Add the new peer:
myself->m_peers.push_back(peer);
Log::info("STKHost", "A client has just connected. There are "
"now %lu peers.", myself->m_peers.size());
Log::debug("STKHost", "Addresses are : %lx, %lx",
stk_event->getPeer(), peer);
} // EVENT_TYPE_CONNECTED
else if (stk_event->getType() == EVENT_TYPE_MESSAGE)
{
TransportAddress stk_addr(peer->getAddress());
Log::verbose("NetworkManager",
"Message, Sender : %s, message = \"%s\"",
stk_addr.toString(/*show port*/false).c_str(),
stk_event->data().std_string().c_str());
} // if message event
// notify for the event now.
ProtocolManager::getInstance()->propagateEvent(stk_event);
} // while enet_host_service
} // while !mustStopListening
@ -273,7 +340,46 @@ bool STKHost::isConnectedTo(const TransportAddress& peer)
return false;
} // isConnectedTo
// ----------------------------------------------------------------------------
void STKHost::removePeer(const STKPeer* peer)
{
if (!peer || !peer->exists()) // peer does not exist (already removed)
return;
TransportAddress addr(peer->getAddress());
Log::debug("STKHost", "Disconnected host: %s", addr.toString().c_str());
// remove the peer:
bool removed = false;
for (unsigned int i = 0; i < m_peers.size(); i++)
{
if (m_peers[i]->isSamePeer(peer) && !removed) // remove only one
{
delete m_peers[i];
m_peers.erase(m_peers.begin() + i, m_peers.begin() + i + 1);
Log::verbose("NetworkManager",
"The peer has been removed from the Network Manager.");
removed = true;
}
else if (m_peers[i]->isSamePeer(peer))
{
Log::fatal("NetworkManager",
"Multiple peers match the disconnected one.");
}
} // for i < m_peers.size()
if (!removed)
Log::warn("NetworkManager", "The peer that has been disconnected was "
"not registered by the Network Manager.");
Log::info("NetworkManager",
"Somebody is now disconnected. There are now %lu peers.",
m_peers.size());
} // removePeer
//-----------------------------------------------------------------------------
uint16_t STKHost::getPort() const
{
struct sockaddr_in sin;
@ -284,4 +390,24 @@ uint16_t STKHost::getPort() const
else
return ntohs(sin.sin_port);
return 0;
}
} // getPort
//-----------------------------------------------------------------------------
/** Sends data to all peers except the specified one.
* \param peer Peer which will not receive the message.
* \param data Data to sent.
* \param reliable If the data should be sent reliable or now.
*/
void STKHost::sendPacketExcept(STKPeer* peer, const NetworkString& data,
bool reliable)
{
for (unsigned int i = 0; i < m_peers.size(); i++)
{
STKPeer* p = m_peers[i];
if (!p->isSamePeer(peer))
{
p->sendPacket(data, reliable);
}
}
} // sendPacketExcept

View File

@ -73,10 +73,14 @@ private:
/** ENet host interfacing sockets. */
Network* m_network;
/** The list of peers connected to this instance. */
std::vector<STKPeer*> m_peers;
/** This computer's public IP address. With lock since it can
* be updated from a separate thread. */
Synchronised<TransportAddress> m_public_address;
/** Stores data about the online game to play. */
GameSetup* m_game_setup;
/** Id of thread listening to enet events. */
@ -120,7 +124,12 @@ public:
virtual GameSetup* setupNewGame();
void setPublicAddress(const TransportAddress& addr);
void abort();
void deleteAllPeers ();
void reset();
void sendPacketExcept(STKPeer* peer,
const NetworkString& data,
bool reliable = true);
void setupServer(uint32_t address, uint16_t port,
int peer_count, int channel_limit,
uint32_t max_incoming_bandwidth,
@ -133,6 +142,7 @@ public:
uint8_t* receiveRawPacket(const TransportAddress& sender,
int max_tries = -1);
bool peerExists(const TransportAddress& peer_address);
void removePeer(const STKPeer* peer);
bool isConnectedTo(const TransportAddress& peer_address);
int mustStopListening();
uint16_t getPort() const;
@ -194,6 +204,14 @@ public:
/** Returns the maximum number of players for this server. */
static int getMaxPlayers() { return m_max_players; }
// --------------------------------------------------------------------
/** Returns a const reference to the list of peers. */
const std::vector<STKPeer*> &getPeers() { return m_peers; }
// --------------------------------------------------------------------
/** Returns the number of currently connected peers. */
unsigned int getPeerCount() { return (int)m_peers.size(); }
}; // class STKHost
#endif // STK_HOST_HPP