[Orxonox-commit 7215] r11829 - code/branches/Masterserver_FS18/src/libraries/network
mdedial at orxonox.net
mdedial at orxonox.net
Thu Mar 22 16:12:24 CET 2018
Author: mdedial
Date: 2018-03-22 16:12:23 +0100 (Thu, 22 Mar 2018)
New Revision: 11829
Modified:
code/branches/Masterserver_FS18/src/libraries/network/Connection.cc
code/branches/Masterserver_FS18/src/libraries/network/Connection.h
code/branches/Masterserver_FS18/src/libraries/network/GamestateManager.cc
code/branches/Masterserver_FS18/src/libraries/network/GamestateManager.h
code/branches/Masterserver_FS18/src/libraries/network/Host.cc
code/branches/Masterserver_FS18/src/libraries/network/Host.h
code/branches/Masterserver_FS18/src/libraries/network/Server.cc
code/branches/Masterserver_FS18/src/libraries/network/ServerConnection.cc
code/branches/Masterserver_FS18/src/libraries/network/ServerConnection.h
Log:
WIP 22.03.18: Begin documenting server-side code
Modified: code/branches/Masterserver_FS18/src/libraries/network/Connection.cc
===================================================================
--- code/branches/Masterserver_FS18/src/libraries/network/Connection.cc 2018-03-22 12:51:59 UTC (rev 11828)
+++ code/branches/Masterserver_FS18/src/libraries/network/Connection.cc 2018-03-22 15:12:23 UTC (rev 11829)
@@ -44,22 +44,40 @@
const boost::posix_time::millisec NETWORK_COMMUNICATION_THREAD_WAIT_TIME(200);
const unsigned int NETWORK_DISCONNECT_TIMEOUT = 500;
+ /**
+ * Constructor
+ * @param firstPeerId The initial value of nextPeerID_
+ */
Connection::Connection(uint32_t firstPeerID):
host_(nullptr), bCommunicationThreadRunning_(false), nextPeerID_(firstPeerID)
{
+ // Global initialization of ENet
enet_initialize();
+
+ // Register enet_deinitialize to be executed when the program exits normally
atexit(enet_deinitialize);
+
+ // Create mutexes for incoming and outgoing events
this->incomingEventsMutex_ = new boost::mutex;
this->outgoingEventsMutex_ = new boost::mutex;
-// this->overallMutex_ = new boost::mutex;
}
+ /**
+ * Destructor
+ */
Connection::~Connection()
{
+ // Delete the mutexes
delete this->incomingEventsMutex_;
delete this->outgoingEventsMutex_;
+
+ // TODO: Why is enet_deinitialize() not called here?
+ // Would make sense, since its counterpart, enet_initialize(), is called in the constructor.
}
+ /**
+ * Start the main communication thread.
+ */
void Connection::startCommunicationThread()
{
this->bCommunicationThreadRunning_ = true;
@@ -66,28 +84,37 @@
this->communicationThread_ = new boost::thread(&Connection::communicationThread, this);
}
+ /**
+ * Stop the main communication thread.
+ */
void Connection::stopCommunicationThread()
{
this->bCommunicationThreadRunning_ = false;
- if( !this->communicationThread_->timed_join(NETWORK_COMMUNICATION_THREAD_WAIT_TIME) )
+ // Wait for peaceful termination
+ if(!this->communicationThread_->timed_join(NETWORK_COMMUNICATION_THREAD_WAIT_TIME))
{
- // force thread to stop
+ // Force thread to stop if the waiting time runs out.
this->communicationThread_->interrupt();
}
delete this->communicationThread_;
}
+ /**
+ * Send an outgoing event of type 'disconnectPeer'.
+ * @param peerID The peer to which the event is sent
+ */
void Connection::disconnectPeer(uint32_t peerID)
{
-// this->overallMutex_->lock();
outgoingEvent outEvent = { peerID, OutgoingEventType::disconnectPeer, nullptr, 0 };
this->outgoingEventsMutex_->lock();
this->outgoingEvents_.push_back(outEvent);
this->outgoingEventsMutex_->unlock();
-// this->overallMutex_->unlock();
}
-
+
+ /**
+ * Send an outgoing event of type 'disconnectPeers'.
+ */
void Connection::disconnectPeers()
{
outgoingEvent outEvent = { 0, OutgoingEventType::disconnectPeers, nullptr, 0 };
@@ -97,59 +124,70 @@
this->outgoingEventsMutex_->unlock();
}
+ /**
+ * Send a packet.
+ * @param packet Pointer to the packet to send
+ * @param peerID The peer to which the event is sent
+ * @param channelId The channel ID
+ */
void Connection::addPacket(ENetPacket* packet, uint32_t peerID, uint8_t channelID)
{
-// this->overallMutex_->lock();
outgoingEvent outEvent = { peerID, OutgoingEventType::sendPacket, packet, channelID };
this->outgoingEventsMutex_->lock();
this->outgoingEvents_.push_back(outEvent);
this->outgoingEventsMutex_->unlock();
-// this->overallMutex_->unlock();
}
+ /**
+ * Send a broadcast packet.
+ * @param packet Pointer to the packet to send
+ * @param channelId The channel ID
+ */
void Connection::broadcastPacket(ENetPacket* packet, uint8_t channelID)
{
-// this->overallMutex_->lock();
outgoingEvent outEvent = { 0, OutgoingEventType::broadcastPacket, packet, channelID };
this->outgoingEventsMutex_->lock();
this->outgoingEvents_.push_back(outEvent);
this->outgoingEventsMutex_->unlock();
-// this->overallMutex_->unlock();
}
+ /**
+ * Main communication thread
+ */
void Connection::communicationThread()
{
ENetEvent event;
-// this->overallMutex_->lock();
- while( bCommunicationThreadRunning_ )
+ while(this->bCommunicationThreadRunning_)
{
// Receive all pending incoming Events (such as packets, connects and disconnects)
- while( enet_host_check_events( this->host_, &event ) > 0 )
+ while(enet_host_check_events(this->host_, &event ) > 0)
{
- processIncomingEvent(event);
+ this->processIncomingEvent(event);
}
-// this->overallMutex_->unlock();
+ // Sleep for 1ms
+ // TODO: Why?
msleep(1);
-// this->overallMutex_->lock();
// Send all waiting outgoing packets
+ // TODO: Why do we need a mutex to read a single variable?
this->outgoingEventsMutex_->lock();
uint32_t outgoingEventsCount = this->outgoingEvents_.size();
this->outgoingEventsMutex_->unlock();
- while( outgoingEventsCount > 0 )
+
+ // TODO: Not convinced about how mutexes are used here, seems kinda pointless
+ while(outgoingEventsCount > 0)
{
-// orxout(verbose, context::network) << "outgoing event" << endl;
this->outgoingEventsMutex_->lock();
outgoingEvent outEvent = this->outgoingEvents_.front();
this->outgoingEvents_.pop_front();
this->outgoingEventsMutex_->unlock();
- processOutgoingEvent(outEvent);
+ this->processOutgoingEvent(outEvent);
this->outgoingEventsMutex_->lock();
outgoingEventsCount = this->outgoingEvents_.size();
@@ -157,19 +195,22 @@
}
// Wait for incoming events (at most NETWORK_WAIT_TIMEOUT ms)
- if( enet_host_service( this->host_, &event, NETWORK_WAIT_TIMEOUT ) > 0 )
+ if(enet_host_service(this->host_, &event, NETWORK_WAIT_TIMEOUT) > 0)
{
- processIncomingEvent(event);
+ this->processIncomingEvent(event);
}
}
-// this->overallMutex_->unlock();
}
+ /**
+ * Handle an incoming event.
+ * @param event The incoming event
+ */
void Connection::processIncomingEvent(ENetEvent& event)
{
incomingEvent inEvent;
// preprocess event
- switch( event.type )
+ switch(event.type)
{
case ENET_EVENT_TYPE_CONNECT:
inEvent = preprocessConnectEvent(event);
@@ -191,27 +232,31 @@
this->incomingEventsMutex_->unlock();
}
+ /**
+ * Send an event.
+ * @param event The event to send
+ */
void Connection::processOutgoingEvent(outgoingEvent& event)
{
ENetPeer* peer;
- switch( event.type )
+ switch(event.type)
{
case OutgoingEventType::sendPacket:
// check whether the peer is still/already in the peer list
- if( this->peerMap_.find(event.peerID) != this->peerMap_.end() )
+ if(this->peerMap_.find(event.peerID) != this->peerMap_.end())
{
peer = this->peerMap_[event.peerID];
- enet_peer_send( peer, event.channelID, event.packet );
+ enet_peer_send(peer, event.channelID, event.packet);
}
else
{
// peer probably already disconnected so just discard packet
- assert(event.peerID<this->nextPeerID_);
+ assert(event.peerID < this->nextPeerID_);
enet_packet_destroy(event.packet);
}
break;
case OutgoingEventType::disconnectPeer:
- if( this->peerMap_.find(event.peerID) != this->peerMap_.end() )
+ if(this->peerMap_.find(event.peerID) != this->peerMap_.end())
{
peer = this->peerMap_[event.peerID];
enet_peer_disconnect(peer, 0);
@@ -219,11 +264,11 @@
else
{
// peer probably already disconnected so just discard disconnect event
- assert(event.peerID<this->nextPeerID_);
+ assert(event.peerID < this->nextPeerID_);
}
break;
case OutgoingEventType::disconnectPeers:
- disconnectPeersInternal();
+ this->disconnectPeersInternal();
break;
case OutgoingEventType::broadcastPacket:
enet_host_broadcast( this->host_, event.channelID, event.packet );
@@ -233,7 +278,6 @@
}
}
-
void Connection::disconnectPeersInternal()
{
for( const auto& mapEntry : this->peerMap_ )
@@ -240,7 +284,7 @@
{
enet_peer_disconnect(mapEntry.second, 0);
}
- uint32_t iterations = NETWORK_DISCONNECT_TIMEOUT/NETWORK_WAIT_TIMEOUT;
+ uint32_t iterations = NETWORK_DISCONNECT_TIMEOUT / NETWORK_WAIT_TIMEOUT;
uint32_t i = 0;
while( this->peerMap_.size() && i++ < iterations )
{
Modified: code/branches/Masterserver_FS18/src/libraries/network/Connection.h
===================================================================
--- code/branches/Masterserver_FS18/src/libraries/network/Connection.h 2018-03-22 12:51:59 UTC (rev 11828)
+++ code/branches/Masterserver_FS18/src/libraries/network/Connection.h 2018-03-22 15:12:23 UTC (rev 11829)
@@ -95,7 +95,7 @@
virtual ~Connection();
protected:
- Connection(uint32_t firstPeerID = NETWORK_PEER_ID_SERVER+1);
+ Connection(uint32_t firstPeerID = NETWORK_PEER_ID_SERVER + 1);
void startCommunicationThread();
void stopCommunicationThread();
@@ -109,9 +109,9 @@
void processQueue();
void waitOutgoingQueue(); // wait for the outgoing queue to become empty (everything processed by communication thread)
- virtual void addPeer(uint32_t peerID)=0;
- virtual void removePeer(uint32_t peerID)=0;
- virtual void processPacket( packet::Packet* packet)=0;
+ virtual void addPeer(uint32_t peerID) = 0;
+ virtual void removePeer(uint32_t peerID) = 0;
+ virtual void processPacket( packet::Packet* packet) = 0;
incomingEvent preprocessConnectEvent(ENetEvent& event);
incomingEvent preprocessDisconnectEvent(ENetEvent& event);
@@ -123,6 +123,7 @@
void disconnectPeersInternal();
ENetHost* host_;
+
private:
void communicationThread();
@@ -129,8 +130,13 @@
boost::thread* communicationThread_;
bool bCommunicationThreadRunning_;
ENetAddress* bindAddress_;
+
+ // Queue for incoming events
std::deque<incomingEvent> incomingEvents_;
+
+ // Queue for outgoing events
std::deque<outgoingEvent> outgoingEvents_;
+
boost::mutex* incomingEventsMutex_;
boost::mutex* outgoingEventsMutex_;
boost::mutex* overallMutex_;
Modified: code/branches/Masterserver_FS18/src/libraries/network/GamestateManager.cc
===================================================================
--- code/branches/Masterserver_FS18/src/libraries/network/GamestateManager.cc 2018-03-22 12:51:59 UTC (rev 11828)
+++ code/branches/Masterserver_FS18/src/libraries/network/GamestateManager.cc 2018-03-22 15:12:23 UTC (rev 11829)
@@ -42,7 +42,6 @@
#include <cassert>
#include <queue>
-// #include <boost/thread/mutex.hpp>
#include "packet/Acknowledgement.h"
#include "packet/Gamestate.h"
@@ -54,7 +53,6 @@
#include "util/Output.h"
#include "util/Clock.h"
#include "util/OrxAssert.h"
-// #include "TrafficControl.h"
namespace orxonox
{
@@ -61,29 +59,31 @@
GamestateManager::GamestateManager() :
currentGamestate_(nullptr), id_(0)
{
-// trafficControl_ = new TrafficControl();
-// threadMutex_ = new boost::mutex();
-// threadPool_ = new ThreadPool();
}
GamestateManager::~GamestateManager()
{
- if( this->currentGamestate_ )
- delete this->currentGamestate_;
- for( const auto& mapEntry : gamestateQueue )
- delete mapEntry.second;
- for( const auto& mapEntryPeer : peerMap_ )
+ if(this->currentGamestate_)
{
- for( const auto& mapEntryGamestate : mapEntryPeer.second.gamestates )
- delete mapEntryGamestate.second;
+ delete this->currentGamestate_;
}
-// this->trafficControl_->destroy();
-// delete this->threadMutex_;
-// delete this->threadPool_;
+
+ for(const auto& gsPair : this->gamestateQueue)
+ {
+ delete gsPair.second;
+ }
+
+ for(const auto& peerPair : this->peerMap_)
+ {
+ for(const auto& gsPair : peerPair.second.gamestates)
+ {
+ delete gsPair.second;
+ }
+ }
}
- bool GamestateManager::update(){
-// cleanup();
+ bool GamestateManager::update()
+ {
return getSnapshot();
}
@@ -90,39 +90,56 @@
bool GamestateManager::addGamestate(packet::Gamestate *gs, unsigned int clientID)
{
assert(gs);
- std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
- if(it!=gamestateQueue.end())
+ // Search the queue for a gamestate for the client
+ std::map<unsigned int, packet::Gamestate*>::iterator it = this->gamestateQueue.find(clientID);
+ if(it != this->gamestateQueue.end())
{
// delete obsolete gamestate
delete it->second;
}
- gamestateQueue[clientID] = gs;
+ // update the client's gamestate
+ this->gamestateQueue[clientID] = gs;
+
return true;
}
+ /**
+ * Process the queued gamestates.
+ */
bool GamestateManager::processGamestates()
{
- if( this->gamestateQueue.empty() )
+ // Queue is empty, nothing to do
+ if(this->gamestateQueue.empty())
+ {
return true;
+ }
+
// now push only the most recent gamestates we received (ignore obsolete ones)
- for(const auto& mapEntry : gamestateQueue)
+ for(const auto& gsPair : this->gamestateQueue)
{
- OrxVerify(processGamestate(mapEntry.second), "ERROR: could not process Gamestate");
- sendAck( mapEntry.second->getID(), mapEntry.second->getPeerID() );
- delete mapEntry.second;
+ OrxVerify(processGamestate(gsPair.second), "ERROR: could not process Gamestate");
+ sendAck(gsPair.second->getID(), gsPair.second->getPeerID());
+ delete gsPair.second;
}
// now clear the queue
- gamestateQueue.clear();
+ this->gamestateQueue.clear();
+
//and call all queued callbacks
NetworkCallbackManager::callCallbacks();
+
return true;
}
+ /**
+ * Send Acknowledgement packet.
+ * @param gamestateId The gamestate ID we want to acknowledge
+ * @param peerID The ID of the peer we want to send the Acknowledgement to
+ */
bool GamestateManager::sendAck(unsigned int gamestateID, uint32_t peerID)
{
- assert( gamestateID != ACKID_NACK );
+ assert(gamestateID != ACKID_NACK);
packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, peerID);
- if( !this->sendPacket(ack))
+ if(!this->sendPacket(ack))
{
orxout(internal_warning, context::network) << "could not ack gamestate: " << gamestateID << endl;
return false;
@@ -134,48 +151,70 @@
}
}
+ /**
+ * Update the current gamestate.
+ */
+ bool GamestateManager::getSnapshot()
+ {
+ // Delete current gamestate
+ if (this->currentGamestate_ != nullptr)
+ {
+ delete this->currentGamestate_;
+ }
- bool GamestateManager::getSnapshot(){
- if ( currentGamestate_ != nullptr )
- delete currentGamestate_;
uint8_t gsMode;
- if( GameMode::isMaster() )
+ if(GameMode::isMaster())
+ {
gsMode = packet::GAMESTATE_MODE_SERVER;
+ }
else
+ {
gsMode = packet::GAMESTATE_MODE_CLIENT;
+ }
+
uint32_t newID;
- if( GameMode::isMaster() )
- newID = ++id_;
+ if(GameMode::isMaster())
+ {
+ newID = ++this->id_;
+ }
else
{
- assert(peerMap_.size()!=0);
- newID = peerMap_[NETWORK_PEER_ID_SERVER].lastReceivedGamestateID;
- if( newID == GAMESTATEID_INITIAL )
+ assert(this->peerMap_.size() != 0);
+ newID = this->peerMap_[NETWORK_PEER_ID_SERVER].lastReceivedGamestateID;
+ if(newID == GAMESTATEID_INITIAL)
{
return false;
}
}
- currentGamestate_ = new packet::Gamestate();
-
- if(!currentGamestate_->collectData(newID, gsMode))
- { //we have no data to send
- delete currentGamestate_;
- currentGamestate_=nullptr;
+ // Create a new gamestate
+ this->currentGamestate_ = new packet::Gamestate();
+ if(!this->currentGamestate_->collectData(newID, gsMode))
+ {
+ // we have no data to send
+ delete this->currentGamestate_;
+ this->currentGamestate_ = nullptr;
return false;
}
+
return true;
}
+ /**
+ * Return a vector with the gamestates of all peers.
+ */
std::vector<packet::Gamestate*> GamestateManager::getGamestates()
{
- if(!currentGamestate_)
+ // Current gamestate is empty
+ if(!this->currentGamestate_){
return std::vector<packet::Gamestate*>();
+ }
+
std::vector<packet::Gamestate*> peerGamestates;
-
- for( const auto& mapEntry : peerMap_ )
+ // TODO: mapEntry is an incredibly bad name
+ for(const auto& mapEntry : this->peerMap_)
{
- if( !mapEntry.second.isSynched )
+ if(!mapEntry.second.isSynched)
{
orxout(verbose_more, context::network) << "Server: not sending gamestate" << endl;
continue;
@@ -197,38 +236,28 @@
peerGamestates.push_back(nullptr); // insert an empty gamestate* to be changed
finishGamestate( peerID, peerGamestates.back(), baseGamestate, currentGamestate_ );
- if( peerGamestates.back()==nullptr )
+ if(peerGamestates.back() == nullptr)
+ {
// nothing to send to remove pointer from vector
peerGamestates.pop_back();
- //FunctorMember<GamestateManager>* functor =
-// ExecutorMember<GamestateManager>* executor = createExecutor( createFunctor(&GamestateManager::finishGamestate, this) );
-// executor->setDefaultValues( cid, &clientGamestates.back(), client, currentGamestate_ );
-// (*static_cast<Executor*>(executor))();
-// this->threadPool_->passFunction( executor, true );
-// (*functor)( cid, &(clientGamestates.back()), client, currentGamestate_ );
+ }
}
-// threadPool_->synchronise();
-
return peerGamestates;
}
- void GamestateManager::finishGamestate( unsigned int peerID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) {
- //why are we searching the same client's gamestate id as we searched in
- //Server::sendGameState?
+ void GamestateManager::finishGamestate(unsigned int peerID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate)
+ {
// save the (undiffed) gamestate in the clients gamestate map
- //chose wheather the next gamestate is the first or not
+ // choose whether the next gamestate is the first or not
-// packet::Gamestate *gs = gamestate->doSelection(clientID, 20000);
-// packet::Gamestate* gs = new packet::Gamestate(*gamestate);
-// packet::Gamestate* gs = gamestate;
+ // Create a copy of the gamestate
+ // TODO: Does this actually create a copy of the gamestate?
packet::Gamestate *gs = new packet::Gamestate(*gamestate); //this is neccessary because the gamestate are being kept (to diff them later on) for each client seperately
-// packet::Gamestate *gs = new packet::Gamestate();
-// gs->collectData( id_, 0x1 );
-// this->threadMutex_->lock();
- peerMap_[peerID].gamestates[gamestate->getID()]=gs;
-// this->threadMutex_->unlock();
+ this->peerMap_[peerID].gamestates[gamestate->getID()] = gs;
+
+ // Start the clock
Clock clock;
clock.capture();
@@ -235,7 +264,7 @@
if(base)
{
packet::Gamestate *diffed1 = gs->diffVariables(base);
- if( diffed1->getDataSize() == 0 )
+ if(diffed1->getDataSize() == 0)
{
delete diffed1;
destgamestate = nullptr;
@@ -248,131 +277,145 @@
gs = new packet::Gamestate(*gs);
}
-
-// OrxVerify(gs->compressData(), "");
+ // Stop the clock
clock.capture();
orxout(verbose_more, context::network) << "diff and compress time: " << clock.getDeltaTime() << endl;
-// orxout(verbose_more, context::network) << "sending gamestate with id " << gs->getID();
-// if(gamestate->isDiffed())
-// orxout(verbose_more, context::network) << " and baseid " << gs->getBaseID() << endl;
-// else
-// orxout(verbose_more, context::network) << endl;
+
+
gs->setPeerID(peerID);
destgamestate = gs;
}
+ /**
+ * Acknowledge a received gamestate.
+ * @param gamestateID The ID of the gamestate to be acknowledged
+ * @param peerID The ID of the peer to send the Acknowledgement to
+ */
bool GamestateManager::ackGamestate(unsigned int gamestateID, unsigned int peerID)
{
-// ClientInformation *temp = ClientInformation::findClient(peerID);
-// assert(temp);
+ // Search for the peer in the peer map
std::map<uint32_t, peerInfo>::iterator it = this->peerMap_.find(peerID);
- assert(it!=this->peerMap_.end());
+ assert(it != this->peerMap_.end());
+
unsigned int curid = it->second.lastAckedGamestateID;
assert(gamestateID != ACKID_NACK);
-// if(gamestateID == ACKID_NACK){
-// it->second.lastAckedGamestateID = GAMESTATEID_INITIAL;
-// // temp->setGamestateID(GAMESTATEID_INITIAL);
-// // now delete all saved gamestates for this client
-// std::map<uint32_t, packet::Gamestate*>::iterator it2;
-// for(it2 = it->second.gamestates.begin(); it2!=it->second.gamestates.end(); ++it2 ){
-// delete it2->second;
-// }
-// it->second.gamestates.clear();
-// return true;
-// }
-// assert(curid==GAMESTATEID_INITIAL || curid<=gamestateID); // this line is commented out because acknowledgements are unreliable and may arrive in distorted order
- if( gamestateID <= curid && curid != GAMESTATEID_INITIAL )
+ // The gamestate has already been acknowledged, nothing to do
+ if(gamestateID <= curid && curid != GAMESTATEID_INITIAL)
+ {
return true;
-orxout(verbose, context::network) << "acking gamestate " << gamestateID << " for peerID: " << peerID << " curid: " << curid << endl;
+ }
+
+ orxout(verbose, context::network) << "acking gamestate " << gamestateID << " for peerID: " << peerID << " curid: " << curid << endl;
std::map<uint32_t, packet::Gamestate*>::iterator it2;
- for( it2=it->second.gamestates.begin(); it2!=it->second.gamestates.end(); )
+ for (it2 = it->second.gamestates.begin(); it2 != it->second.gamestates.end();)
{
- if( it2->second->getID() < gamestateID )
+ if(it2->second->getID() < gamestateID)
{
delete it2->second;
it->second.gamestates.erase(it2++);
}
else
+ {
++it2;
+ }
}
-// std::map<unsigned int, packet::Gamestate*>::iterator it;
-// for(it = gamestateMap_[peerID].begin(); it!=gamestateMap_[peerID].end() && it->first<gamestateID; ){
-// delete it->second;
-// gamestateMap_[peerID].erase(it++);
-// }
+ // update the last acked gamestate
it->second.lastAckedGamestateID = gamestateID;
-// temp->setGamestateID(gamestateID);
-// TrafficControl::processAck(peerID, gamestateID);
+
return true;
}
+ /**
+ * Return the ID of the last received gamestate for a certain peer
+ * @param peerID The ID of the peer\
+ */
uint32_t GamestateManager::getLastReceivedGamestateID(unsigned int peerID)
{
- assert( this->peerMap_.find(peerID)!=this->peerMap_.end() );
- if( this->peerMap_.find(peerID) != this->peerMap_.end() )
+ if(this->peerMap_.find(peerID) != this->peerMap_.end())
+ {
return this->peerMap_[peerID].lastReceivedGamestateID;
+ }
else
+ {
return GAMESTATEID_INITIAL;
+ }
}
-
+ /**
+ * Add a peer to the game.
+ * @param peerID The ID of the peer to add.
+ */
void GamestateManager::addPeer(uint32_t peerID)
{
- assert(peerMap_.find(peerID)==peerMap_.end());
- peerMap_[peerID].peerID = peerID;
- peerMap_[peerID].lastReceivedGamestateID = GAMESTATEID_INITIAL;
- peerMap_[peerID].lastAckedGamestateID = GAMESTATEID_INITIAL;
- if( GameMode::isMaster() )
- peerMap_[peerID].isSynched = false;
+ // Ensure that the peer doesn't already exist.
+ assert(this->peerMap_.find(peerID) == this->peerMap_.end());
+
+ // Create the peerInfo struct for the peer
+ this->peerMap_[peerID].peerID = peerID;
+ this->peerMap_[peerID].lastReceivedGamestateID = GAMESTATEID_INITIAL;
+ this->peerMap_[peerID].lastAckedGamestateID = GAMESTATEID_INITIAL;
+ if(GameMode::isMaster())
+ {
+ this->peerMap_[peerID].isSynched = false;
+ }
else
- peerMap_[peerID].isSynched = true;
+ {
+ this->peerMap_[peerID].isSynched = true;
+ }
}
+ /**
+ * Remove a peer from the game.
+ * @param peerID The ID of the peer to be removed
+ */
void GamestateManager::removePeer(uint32_t peerID)
{
- assert(peerMap_.find(peerID)!=peerMap_.end());
- for( const auto& mapEntry : peerMap_[peerID].gamestates )
+ // Make sure that the peer exists
+ assert(this->peerMap_.find(peerID) != this->peerMap_.end());
+
+ for (const auto& mapEntry : this->peerMap_[peerID].gamestates)
{
delete mapEntry.second;
}
- peerMap_.erase(peerMap_.find(peerID));
+ this->peerMap_.erase(this->peerMap_.find(peerID));
}
-
-// void GamestateManager::removeClient(ClientInformation* client){
-// assert(client);
-// std::map<unsigned int, std::map<unsigned int, packet::Gamestate*>>::iterator clientMap = gamestateMap_.find(client->getID());
-// // first delete all remained gamestates
-// std::map<unsigned int, packet::Gamestate*>::iterator it;
-// for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
-// delete it->second;
-// // now delete the clients gamestatemap
-// gamestateMap_.erase(clientMap);
-// }
-
+ /**
+ * Process an incoming Gamestate packet.
+ * @param gs Pointer to the incoming Gamestate packet
+ */
bool GamestateManager::processGamestate(packet::Gamestate *gs)
{
+ // Decompress if necessary
if(gs->isCompressed())
{
OrxVerify(gs->decompressData(), "ERROR: could not decompress Gamestate");
}
assert(!gs->isDiffed());
+
uint8_t gsMode;
- if( GameMode::isMaster() )
+ if(GameMode::isMaster())
+ {
gsMode = packet::GAMESTATE_MODE_SERVER;
+ }
else
+ {
gsMode = packet::GAMESTATE_MODE_CLIENT;
- if( gs->spreadData(gsMode) )
+ }
+
+ if(gs->spreadData(gsMode))
{
this->peerMap_[gs->getPeerID()].lastReceivedGamestateID = gs->getID();
return true;
}
else
+ {
return false;
+ }
}
}
Modified: code/branches/Masterserver_FS18/src/libraries/network/GamestateManager.h
===================================================================
--- code/branches/Masterserver_FS18/src/libraries/network/GamestateManager.h 2018-03-22 12:51:59 UTC (rev 11828)
+++ code/branches/Masterserver_FS18/src/libraries/network/GamestateManager.h 2018-03-22 15:12:23 UTC (rev 11829)
@@ -61,9 +61,9 @@
* a: last Gamestate a client has received
* b: new Gamestate
* x: diffed and compressed gamestate
- * x=(a^b)
- * b=(a^x)
- * diff(a,diff(a,x))=x (hope this is correct)
+ * x = (a ^ b)
+ * b = (a ^ x)
+ * diff(a, diff(a, x)) = x (hope this is correct)
* @author Oliver Scheuss
*/
class _NetworkExport GamestateManager: public GamestateHandler
@@ -74,7 +74,7 @@
uint32_t lastReceivedGamestateID; //!< id of the last gamestate which was received (and processed) from the peer
uint32_t lastAckedGamestateID; //!< id of the last gamestate on which we received an ack from the peer
bool isSynched;
- std::map< uint32_t, packet::Gamestate* > gamestates;
+ std::map<uint32_t, packet::Gamestate*> gamestates;
};
public:
@@ -85,7 +85,7 @@
virtual bool addGamestate(packet::Gamestate *gs, unsigned int peerID) override;
virtual bool ackGamestate(unsigned int gamestateID, unsigned int peerID) override;
virtual uint32_t getLastReceivedGamestateID( unsigned int peerID ) override;
- virtual uint32_t getCurrentGamestateID() override{ if( currentGamestate_) return currentGamestate_->getID(); else return GAMESTATEID_INITIAL; }
+ virtual uint32_t getCurrentGamestateID() override { if(currentGamestate) return currentGamestate_->getID(); else return GAMESTATEID_INITIAL; }
bool processGamestates();
bool sendAck(unsigned int gamestateID, uint32_t peerID);
@@ -97,24 +97,26 @@
void addPeer( uint32_t peerID );
void setSynched( uint32_t peerID )
- { assert(peerMap_.find(peerID)!=peerMap_.end()); peerMap_[peerID].isSynched = true; }
+ { assert(peerMap_.find(peerID) != peerMap_.end()); peerMap_[peerID].isSynched = true; }
void removePeer( uint32_t peerID );
- bool hasPeers(){ return this->peerMap_.size()!=0; }
-// void removeClient(ClientInformation *client);
+ bool hasPeers(){ return this->peerMap_.size() != 0; }
+
protected:
virtual bool sendPacket( packet::Packet* packet ) = 0;
+
private:
bool processGamestate(packet::Gamestate *gs);
-// std::map<unsigned int, std::map<unsigned int, packet::Gamestate*>> gamestateMap_;
+ // TODO: What is the purpose of the gamestateQueue?
std::map<unsigned int, packet::Gamestate*> gamestateQueue;
-// std::map<unsigned int, uint32_t> lastProcessedGamestateID_;
+
+ // Each peerID maps to a peerInfo struct
std::map<uint32_t, peerInfo> peerMap_;
+
+ // always contains the latest gamestate
packet::Gamestate* currentGamestate_;
-// TrafficControl *trafficControl_;
unsigned int id_;
-// boost::mutex* threadMutex_;
- ThreadPool* /*thread*/Pool_;
+ ThreadPool* Pool_;
};
}
Modified: code/branches/Masterserver_FS18/src/libraries/network/Host.cc
===================================================================
--- code/branches/Masterserver_FS18/src/libraries/network/Host.cc 2018-03-22 12:51:59 UTC (rev 11828)
+++ code/branches/Masterserver_FS18/src/libraries/network/Host.cc 2018-03-22 15:12:23 UTC (rev 11829)
@@ -43,9 +43,7 @@
SetConsoleCommand(__CC_printRTT_group, __CC_printRTT_name, &Host::printRTT);
- // Host* Host::instance_=nullptr;
- uint32_t Host::clientID_s=0;
-// uint32_t Host::shipID_s=-1;
+ uint32_t Host::clientID_s = 0;
std::vector<Host*> Host::instances_s;
/**
@@ -53,9 +51,11 @@
*/
Host::Host()
{
- // assert(instance_==nullptr);
- instances_s.push_back(this);
+ Host::instances_s.push_back(this);
+
+ // TODO: What does this do?
ModifyConsoleCommand(__CC_printRTT_group, __CC_printRTT_name).setObject(this);
+
this->bIsActive_ = false;
}
@@ -65,8 +65,8 @@
*/
Host::~Host()
{
- assert( std::find( instances_s.begin(), instances_s.end(), this )!=instances_s.end() );
- instances_s.erase(std::find( instances_s.begin(), instances_s.end(), this ));
+ assert(std::find( instances_s.begin(), instances_s.end(), this ) != instances_s.end());
+ Host::instances_s.erase(std::find( instances_s.begin(), instances_s.end(), this ));
ModifyConsoleCommand(__CC_printRTT_group, __CC_printRTT_name).setObject(nullptr);
}
@@ -79,9 +79,9 @@
*/
void Host::addPacket(ENetPacket *packet, int clientID, uint8_t channelID)
{
- for(Host* host : instances_s)
+ for (Host* host : instances_s)
{
- if( host->isActive() )
+ if (host->isActive())
{
host->queuePacket(packet, clientID, channelID);
}
@@ -96,9 +96,13 @@
*/
void Host::sendChat(const std::string& message, unsigned int sourceID, unsigned int targetID)
{
- for(Host* host : instances_s)
- if( host->isActive() )
+ for (Host* host : instances_s)
+ {
+ if (host->isActive())
+ {
host->doSendChat(message, sourceID, targetID);
+ }
+ }
}
/**
@@ -107,32 +111,43 @@
void Host::doReceiveChat(const std::string& message, unsigned int sourceID, unsigned int targetID)
{
for (NetworkChatListener* listener : ObjectList<NetworkChatListener>())
+ {
listener->incomingChat(message, sourceID);
+ }
}
bool Host::isServer()
{
- for (Host* host : instances_s)
+ for (Host* host : Host::instances_s)
{
- if( host->isActive() )
+ if (host->isActive())
{
- if( host->isServer_() )
+ if (host->isServer_())
+ {
return true;
+ }
}
}
return false;
}
+ /**
+ * Singleton implementation. Return the first active instance.
+ */
Host* Host::getActiveInstance()
{
std::vector<Host*>::iterator it = Host::instances_s.begin();
- while( it != Host::instances_s.end() )
+ while (it != Host::instances_s.end())
{
- if( (*it)->isActive() )
+ if ((*it)->isActive())
+ {
return *it;
+ }
else
+ {
++it;
+ }
}
return nullptr;
}
Modified: code/branches/Masterserver_FS18/src/libraries/network/Host.h
===================================================================
--- code/branches/Masterserver_FS18/src/libraries/network/Host.h 2018-03-22 12:51:59 UTC (rev 11828)
+++ code/branches/Masterserver_FS18/src/libraries/network/Host.h 2018-03-22 15:12:23 UTC (rev 11829)
@@ -39,7 +39,7 @@
const unsigned int CLIENTID_SERVER = 0;
const unsigned int NETWORK_FREQUENCY = 25;
- const float NETWORK_PERIOD = 1.0f/NETWORK_FREQUENCY;
+ const float NETWORK_PERIOD = 1.0f / NETWORK_FREQUENCY;
/**
* @brief Base class of Server and Client
@@ -54,7 +54,7 @@
friend class packet::Chat;
private:
- virtual void queuePacket(ENetPacket *packet, int clientID, uint8_t channelID)=0;
+ virtual void queuePacket(ENetPacket *packet, int clientID, uint8_t channelID) = 0;
virtual bool isServer_()=0;
protected:
@@ -62,8 +62,8 @@
virtual ~Host();
void setActive( bool bActive ){ bIsActive_ = bActive; }
- virtual void doSendChat(const std::string& message, unsigned int sourceID, unsigned int targetID)=0;
- virtual void doReceiveChat(const std::string& message, unsigned int sourceID, unsigned int targetID)=0;
+ virtual void doSendChat(const std::string& message, unsigned int sourceID, unsigned int targetID) = 0;
+ virtual void doReceiveChat(const std::string& message, unsigned int sourceID, unsigned int targetID) = 0;
public:
static Host* getActiveInstance();
@@ -73,8 +73,9 @@
static void setClientID(unsigned int id){ clientID_s = id; }
static bool isServer();
static void sendChat(const std::string& message, unsigned int sourceID, unsigned int targetID);
- virtual void printRTT()=0;
+ virtual void printRTT() = 0;
bool isActive(){ return bIsActive_; }
+
private:
static uint32_t clientID_s;
static std::vector<Host*> instances_s;
Modified: code/branches/Masterserver_FS18/src/libraries/network/Server.cc
===================================================================
--- code/branches/Masterserver_FS18/src/libraries/network/Server.cc 2018-03-22 12:51:59 UTC (rev 11828)
+++ code/branches/Masterserver_FS18/src/libraries/network/Server.cc 2018-03-22 15:12:23 UTC (rev 11829)
@@ -54,7 +54,6 @@
#include "packet/FunctionIDs.h"
#include "packet/Gamestate.h"
#include "packet/Welcome.h"
-// #include "ClientInformation.h"
#include "FunctionCallManager.h"
#include "GamestateManager.h"
@@ -68,21 +67,19 @@
*/
Server::Server()
{
- this->timeSinceLastUpdate_=0;
+ this->timeSinceLastUpdate_ = 0;
}
+ /**
+ * Constructor
+ * @param port Port to listen on
+ */
Server::Server(int port)
{
- this->setPort( port );
- this->timeSinceLastUpdate_=0;
+ this->setPort(port);
+ this->timeSinceLastUpdate_ = 0;
}
-/*
- Server::Server(int port, const std::string name)
- {
- this->setPort( port );
- this->timeSinceLastUpdate_=0;
- this->serverName_=name;
- }*/
+
/**
* Constructor
* @param port Port to listen on
@@ -90,9 +87,9 @@
*/
Server::Server(int port, const std::string& bindAddress)
{
- this->setPort( port );
- this->setBindAddress( bindAddress );
- this->timeSinceLastUpdate_=0;
+ this->setPort(port);
+ this->setBindAddress(bindAddress);
+ this->timeSinceLastUpdate_ = 0;
}
/**
@@ -155,7 +152,7 @@
// receive and process incoming discovery packets
LANDiscoverable::update();
- if ( GamestateManager::hasPeers() )
+ if (GamestateManager::hasPeers())
{
// process incoming gamestates
GamestateManager::processGamestates();
@@ -162,16 +159,15 @@
FunctionCallManager::processBufferedFunctionCalls();
// send function calls to clients
- FunctionCallManager::sendCalls( static_cast<Host*>(this) );
+ FunctionCallManager::sendCalls(static_cast<Host*>(this));
- //this steers our network frequency
- timeSinceLastUpdate_+=time.getDeltaTime();
- if(timeSinceLastUpdate_>=NETWORK_PERIOD)
+ // this steers our network frequency
+ timeSinceLastUpdate_ += time.getDeltaTime();
+ if(timeSinceLastUpdate_ >= NETWORK_PERIOD)
{
- timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD;
+ timeSinceLastUpdate_ -= static_cast<unsigned int>(timeSinceLastUpdate_ / NETWORK_PERIOD) * NETWORK_PERIOD;
updateGamestate();
}
-// sendPackets(); // flush the enet queue
}
}
@@ -181,57 +177,53 @@
}
/**
- * @brief: returns ping time to client in milliseconds
+ * Return ping time to client in milliseconds.
*/
unsigned int Server::getRTT(unsigned int clientID)
{
-// assert(ClientInformation::findClient(clientID));
-// return ClientInformation::findClient(clientID)->getRTT();
- // TODO: reimplement
+ // TODO: Implement
return 0;
}
+ /**
+ * Print ping time to client in milliseconds.
+ */
void Server::printRTT()
{
-// for( ClientInformation* temp=ClientInformation::getBegin(); temp!=nullptr; temp=temp->next() )
-// orxout(message) << "Round trip time to client with ID: " << temp->getID() << " is " << temp->getRTT() << " ms" << endl;
+ // TODO: Implement
}
/**
- * @brief: return packet loss ratio to client (scales from 0 to 1)
+ * Return packet loss ratio to client (scales from 0 to 1).
*/
float Server::getPacketLoss(unsigned int clientID)
{
-// assert(ClientInformation::findClient(clientID));
-// return ClientInformation::findClient(clientID)->getPacketLoss();
+ // TODO: Implement
return 0.;
}
/**
- * takes a new snapshot of the gamestate and sends it to the clients
- */
+ * Take a new snapshot of the gamestate and send it to the clients.
+ */
void Server::updateGamestate()
{
- if( this->clientIDs_.size()==0 )
- //no client connected
+ if(this->clientIDs_.size() == 0)
+ {
+ // no client connected
return;
+ }
GamestateManager::update();
-// orxout(verbose_more, context::network) << "Server: one gamestate update complete, goig to sendGameState" << endl;
- //orxout(verbose_more, context::network) << "updated gamestate, sending it" << endl;
- //if(clients->getGamestateID()!=GAMESTATEID_INITIAL)
sendGameStates();
sendObjectDeletes();
-// orxout(verbose_more, context::network) << "Server: one sendGameState turn complete, repeat in next tick" << endl;
- //orxout(verbose_more, context::network) << "sent gamestate" << endl;
}
/**
- * sends the current gamestate to all peers
- */
+ * Send the current gamestate to all peers.
+ */
bool Server::sendGameStates()
{
std::vector<packet::Gamestate*> gamestates = GamestateManager::getGamestates();
- for( packet::Gamestate* gamestate : gamestates )
+ for(packet::Gamestate* gamestate : gamestates)
{
gamestate->send(static_cast<Host*>(this));
}
@@ -239,13 +231,17 @@
}
+ /**
+ * Send 'DeleteObjects' packet
+ */
bool Server::sendObjectDeletes()
{
-// ClientInformation *temp = ClientInformation::getBegin();
-// if( temp == nullptr )
- //no client connected
- if( this->clientIDs_.size()==0 )
+ // no client connected
+ if(this->clientIDs_.size() == 0)
+ {
return true;
+ }
+
packet::DeleteObjects *del = new packet::DeleteObjects();
if(!del->fetchIDs())
{
@@ -252,41 +248,24 @@
delete del;
return true; //everything ok (no deletes this tick)
}
-// orxout(verbose, context::network) << "sending DeleteObjects" << endl;
-// while(temp != nullptr){
-// if( !(temp->getSynched()) )
-// {
-// orxout(verbose_more, context::network) << "Server: not sending gamestate" << endl;
-// temp=temp->next();
-// continue;
-// }
-// int cid = temp->getID(); //get client id
-// packet::DeleteObjects *cd = new packet::DeleteObjects(*del);
-// assert(cd);
+
del->setPeerID(NETWORK_PEER_ID_BROADCAST);
- if ( !del->send( static_cast<Host*>(this) ) )
+ if (!del->send( static_cast<Host*>(this)))
+ {
orxout(internal_warning, context::network) << "Server: could not broadcast deleteObjects packet" << endl;
-// temp=temp->next();
- // gs gets automatically deleted by enet callback
-// }
-// delete del;
+ }
+
+ // TODO: Possible memory leak?
+ // del is allocated but only deleted if fetchIDs() returns false
+
return true;
}
-
+ /**
+ * Add a new peer to the server.
+ */
void Server::addPeer(uint32_t peerID)
{
-// static unsigned int newid=1;
-//
-// orxout(internal_info, context::network) << "Server: adding client" << endl;
-// ClientInformation *temp = ClientInformation::insertBack(new ClientInformation);
-// if(!temp)
-// {
-// orxout(internal_warning, context::network) << "Server: could not add client" << endl;
-// }
-// temp->setID(newid);
-// temp->setPeer(event->peer);
-
// inform all the listeners
this->clientIDs_.push_back(peerID);
WANDiscoverable::updateClientNumber(this->clientIDs_.size());
@@ -295,64 +274,68 @@
ClientConnectionListener::broadcastClientConnected(peerID);
GamestateManager::addPeer(peerID);
-// ++newid;
-
orxout(internal_info, context::network) << "Server: added client id: " << peerID << endl;
createClient(peerID);
-}
+ }
+ /**
+ * Remove a peer from the server.
+ */
void Server::removePeer(uint32_t peerID)
{
orxout(verbose, context::network) << "removing client from list" << endl;
-// ClientInformation *client = ClientInformation::findClient(&event->peer->address);
-// if(!client)
-// return;
-// else
-// {
- std::vector<uint32_t>::iterator it;
- for( it=this->clientIDs_.begin(); it!=this->clientIDs_.end(); ++it )
- {
- if( *it == peerID )
+
+ // erase the peer from the list
+ std::vector<uint32_t>::iterator it;
+ for(it=this->clientIDs_.begin(); it!=this->clientIDs_.end(); ++it)
{
- this->clientIDs_.erase(it);
- break;
+ if(*it == peerID)
+ {
+ this->clientIDs_.erase(it);
+ break;
+ }
}
- }
- WANDiscoverable::updateClientNumber(this->clientIDs_.size());
- LANDiscoverable::updateClientNumber(this->clientIDs_.size());
- ClientConnectionListener::broadcastClientDisconnected(peerID);
- GamestateManager::removePeer(peerID);
- //ServerConnection::disconnectClient( client );
- //ClientConnectionListener::broadcastClientDisconnected( client->getID() ); //this is done in ClientInformation now
-// delete client;
-// }
+ // TODO: What happens if no peer with this ID is found?
+ // Should probably at least log
+
+ WANDiscoverable::updateClientNumber(this->clientIDs_.size());
+ LANDiscoverable::updateClientNumber(this->clientIDs_.size());
+
+ // Send 'clientDisconnected' message
+ ClientConnectionListener::broadcastClientDisconnected(peerID);
+
+ GamestateManager::removePeer(peerID);
}
+ /**
+ * Process an incoming packet.
+ */
void Server::processPacket(packet::Packet* packet)
{
- if( packet->isReliable() )
+ if(packet->isReliable())
{
- if( this->getLastReceivedGamestateID(packet->getPeerID()) >= packet->getRequiredGamestateID() )
+ if(this->getLastReceivedGamestateID(packet->getPeerID()) >= packet->getRequiredGamestateID())
+ {
packet->process(static_cast<Host*>(this));
+ }
else
+ {
this->packetQueue_.push_back(packet);
+ }
}
else
+ {
packet->process(static_cast<Host*>(this));
+ }
}
-
+ /**
+ * Create a client.
+ */
bool Server::createClient(int clientID)
{
-// ClientInformation *temp = ClientInformation::findClient(clientID);
-// if(!temp)
-// {
-// orxout(internal_error, context::network) << "Server. could not create client with id: " << clientID << endl;
-// return false;
-// }
-// orxout(verbose, context::network) << "Con.Man: creating client id: " << temp->getID() << endl;
// synchronise class ids
syncClassid(clientID);
@@ -360,37 +343,31 @@
// now synchronise functionIDs
packet::FunctionIDs *fIDs = new packet::FunctionIDs();
fIDs->setPeerID(clientID);
- bool b = fIDs->send( static_cast<Host*>(this) );
+ bool b = fIDs->send(static_cast<Host*>(this));
assert(b);
+ // TODO: assert probably isn't the way to go here, as a packet which fails to send will crash the game...
-// temp->setSynched(true);
GamestateManager::setSynched(clientID);
+ // Send 'Welcome' packet to client
orxout(verbose, context::network) << "sending welcome" << endl;
packet::Welcome *w = new packet::Welcome(clientID);
w->setPeerID(clientID);
- b = w->send( static_cast<Host*>(this) );
+ b = w->send(static_cast<Host*>(this));
assert(b);
+ // TODO: assert probably isn't the way to go here, as a packet which fails to send will crash the game...
+
(void)b; // avoid compiler warning
-// packet::Gamestate *g = new packet::Gamestate();
-// g->setPeerID(clientID);
-// b = g->collectData(0,packet::GAMESTATE_MODE_SERVER);
-// assert(b);
-// if(!b)
-// return false; //no data for the client
-// // b = g->compressData();
-// // assert(b);
-// b = g->send( static_cast<Host*>(this) );
-// assert(b);
return true;
}
- void Server::disconnectClient( uint32_t clientID )
+ /**
+ * Disconnect a client.
+ */
+ void Server::disconnectClient(uint32_t clientID)
{
- ServerConnection::disconnectClient( clientID );
- GamestateManager::removePeer( clientID );
- // inform all the listeners
- // ClientConnectionListener::broadcastClientDisconnected(client->getID()); // this is done in ClientInformation now
+ ServerConnection::disconnectClient(clientID);
+ GamestateManager::removePeer(clientID);
}
/**
@@ -403,16 +380,20 @@
{
// check if the target exists. just ignore the message otherwise
if (!this->isValidTarget(targetID)) // TODO: remove this if an invalid clientIDs don't trigger assertions anymore
+ {
return;
+ }
// send the message to the target
packet::Chat* packet = new packet::Chat(message, sourceID, targetID);
packet->setPeerID(targetID);
- packet->send( static_cast<Host*>(this) );
+ packet->send(static_cast<Host*>(this));
// if the target is (or includes) this host as well, call the parent function which passes the message to the listeners
if (targetID == NETWORK_PEER_ID_BROADCAST || targetID == Host::getPlayerID())
+ {
Host::doReceiveChat(message, sourceID, targetID);
+ }
}
/**
@@ -430,12 +411,20 @@
*/
bool Server::isValidTarget(unsigned int targetID)
{
+ // Broadcast or server ID are okay
if (targetID == NETWORK_PEER_ID_BROADCAST || targetID == NETWORK_PEER_ID_SERVER)
+ {
return true;
+ }
- for( uint32_t id : this->clientIDs_ )
- if( id == targetID )
+ // IDs in the client list are okay also
+ for(uint32_t id : this->clientIDs_)
+ {
+ if(id == targetID)
+ {
return true;
+ }
+ }
return false;
}
@@ -442,13 +431,16 @@
void Server::syncClassid(unsigned int clientID)
{
- int failures=0;
packet::ClassID *classid = new packet::ClassID();
classid->setPeerID(clientID);
- while(!classid->send( static_cast<Host*>(this) ) && failures < 10){
+ // TODO: Better to do this with a for loop
+ int failures = 0;
+ while(!classid->send(static_cast<Host*>(this)) && failures < 10)\
+ {
failures++;
}
assert(failures<10);
+ // TODO: assert probably isn't the way to go here, as 10 failed packets will crash the game...
orxout(verbose, context::network) << "syncClassid:\tall synchClassID packets have been sent" << endl;
}
Modified: code/branches/Masterserver_FS18/src/libraries/network/ServerConnection.cc
===================================================================
--- code/branches/Masterserver_FS18/src/libraries/network/ServerConnection.cc 2018-03-22 12:51:59 UTC (rev 11828)
+++ code/branches/Masterserver_FS18/src/libraries/network/ServerConnection.cc 2018-03-22 15:12:23 UTC (rev 11829)
@@ -35,35 +35,56 @@
#include "util/Output.h"
#include <util/Sleep.h>
-// #include "ClientInformation.h"
namespace orxonox
{
+ // TODO: Calls to the Connection superclass are done as follows:
+ // Connection::startCommunicationThread()
+ // However, these methods are not overridden.
+ // Why can't we just do this->startCommunicationThread()?
+
+ /**
+ * Constructor
+ */
ServerConnection::ServerConnection():
bListening_(false)
{
this->bindAddress_ = new ENetAddress();
-// memset(this->bindAddress_, 0, sizeof(ENetAddress));
this->bindAddress_->host = ENET_HOST_ANY;
this->bindAddress_->port = NETWORK_PORT;
this->bindAddress_->scopeID = 0;
}
+ /**
+ * Destructor
+ */
ServerConnection::~ServerConnection()
{
- if ( this->bListening_ )
- closeListener();
+ if (this->bListening_)
+ {
+ this->closeListener();
+ }
delete this->bindAddress_;
}
- void ServerConnection::setBindAddress( const std::string& bindAddress )
+ /**
+ * Set address on which to listen.
+ * @param bindAddress The address on which to listen
+ */
+ void ServerConnection::setBindAddress(const std::string& bindAddress)
{
- if (enet_address_set_host (this->bindAddress_, bindAddress.c_str()) < 0)
- orxout(internal_error, context::network) << "Could not resolve \"" << bindAddress << "\"." << endl;
+ if (enet_address_set_host(this->bindAddress_, bindAddress.c_str()) < 0)
+ {
+ orxout(internal_error, context::network) << "Could not resolve \"" << bindAddress << "\"." << endl;
+ }
}
- void ServerConnection::setPort( unsigned int port ) {
+ /**
+ * Set port on which to listen on.
+ * @param port The port on which to listen on.
+ */
+ void ServerConnection::setPort(unsigned int port) {
this->bindAddress_->port = port;
}
@@ -72,7 +93,7 @@
// create host
this->host_ = enet_host_create(this->bindAddress_, NETWORK_MAX_CONNECTIONS, NETWORK_CHANNEL_COUNT, 0, 0);
- if ( this->host_ == nullptr )
+ if (this->host_ == nullptr)
{
orxout(internal_error, context::network) << "ServerConnection: host_ == nullptr" << endl;
return false;
@@ -80,13 +101,22 @@
// enable compression
this->enableCompression();
+
+ // ensure that either IPv4 or IPv6 succeeded
assert( this->host_->socket4 != ENET_SOCKET_NULL || this->host_->socket6 != ENET_SOCKET_NULL );
+
if (this->host_->socket4 == ENET_SOCKET_NULL)
+ {
orxout(internal_warning, context::network) << "IPv4 Socket failed." << endl;
+ }
else if (this->host_->socket6 == ENET_SOCKET_NULL)
+ {
orxout(internal_warning, context::network) << "IPv6 Socket failed." << endl;
+ }
else
+ {
orxout(internal_info, context::network) << "Using IPv4 and IPv6 Sockets." << endl;
+ }
// start communication thread
Connection::startCommunicationThread();
@@ -94,9 +124,12 @@
return true;
}
+ /**
+ * Stop listening.
+ */
bool ServerConnection::closeListener()
{
- this->bListening_=false;
+ this->bListening_ = false;
disconnectClients();
Connection::stopCommunicationThread();
enet_host_destroy(this->host_);
@@ -103,34 +136,37 @@
return true;
}
+ /**
+ * Add outgoing packet to queue.
+ * @param packet The packet to send
+ * @param clientID The ID of the recipient
+ * @param channelID The channel ID
+ * TODO: Not sure yet how this actually works
+ */
void ServerConnection::addPacket(ENetPacket *packet, unsigned int clientID, uint8_t channelID)
{
- if ( clientID == NETWORK_PEER_ID_BROADCAST )
+ if (clientID == NETWORK_PEER_ID_BROADCAST)
{
broadcastPacket(packet, channelID);
}
else
{
-// ClientInformation *temp = ClientInformation::findClient(clientID);
-// if(!temp){
-// orxout(internal_warning, context::network) << "C.Man: addPacket findClient failed" << endl;
-// }
Connection::addPacket(packet, clientID, channelID);
}
}
-// void ServerConnection::disconnectClient(ClientInformation *client)
-// {
-// Connection::disconnectPeer( client->getPeer() );
-// }
-
+ /**
+ * Terminate connection with a peer.
+ * @param clientID The peer with which to terminate the connection.
+ */
void ServerConnection::disconnectClient(int clientID)
{
-// ClientInformation *client = ClientInformation::findClient(clientID);
-// if(client)
Connection::disconnectPeer(clientID);
}
+ /**
+ * Disconnect all peers.
+ */
void ServerConnection::disconnectClients()
{
Connection::disconnectPeers();
@@ -137,22 +173,4 @@
Connection::waitOutgoingQueue();
return;
}
-
-
-// int ServerConnection::getClientID(ENetPeer* peer)
-// {
-// return getClientID(&(peer->address));
-// }
-
-// int ServerConnection::getClientID(ENetAddress* address)
-// {
-// return ClientInformation::findClient(address)->getID();
-// }
-//
-// ENetPeer *ServerConnection::getClientPeer(int clientID)
-// {
-// return ClientInformation::findClient(clientID)->getPeer();
-// }
-
-
}
Modified: code/branches/Masterserver_FS18/src/libraries/network/ServerConnection.h
===================================================================
--- code/branches/Masterserver_FS18/src/libraries/network/ServerConnection.h 2018-03-22 12:51:59 UTC (rev 11828)
+++ code/branches/Masterserver_FS18/src/libraries/network/ServerConnection.h 2018-03-22 15:12:23 UTC (rev 11829)
@@ -46,7 +46,8 @@
namespace orxonox
{
- class _NetworkExport ServerConnection : public Connection{
+ class _NetworkExport ServerConnection : public Connection
+ {
public:
~ServerConnection();
@@ -56,19 +57,14 @@
bool openListener();
bool closeListener();
void addPacket(ENetPacket *packet, unsigned int ID, uint8_t channelID);
-// virtual void disconnectClient(ClientInformation *client);
void disconnectClient(int clientID);
+
protected:
ServerConnection();
void disconnectClients();
private:
-// int getClientID(ENetPeer* peer);
-// int getClientID(ENetAddress* address);
-// ENetPeer* getClientPeer(int clientID);
-
ENetAddress* bindAddress_;
-
bool bListening_;
};
More information about the Orxonox-commit
mailing list