Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
May 30, 2018, 2:56:24 PM (6 years ago)
Author:
patricwi
Message:

Merged Masterserver

Location:
code/branches/PresentationFS18
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/PresentationFS18

  • code/branches/PresentationFS18/src/libraries/network/GamestateManager.cc

    r11071 r12020  
    4343#include <cassert>
    4444#include <queue>
    45 // #include <boost/thread/mutex.hpp>
    4645
    4746#include "packet/Acknowledgement.h"
     
    5554#include "util/Clock.h"
    5655#include "util/OrxAssert.h"
    57 // #include "TrafficControl.h"
    5856
    5957namespace orxonox
     
    6260  currentGamestate_(nullptr), id_(0)
    6361  {
    64 //     trafficControl_ = new TrafficControl();
    65 //     threadMutex_ = new boost::mutex();
    66 //     threadPool_ = new ThreadPool();
    6762  }
    6863
    6964  GamestateManager::~GamestateManager()
    7065  {
    71     if( this->currentGamestate_ )
    72         delete this->currentGamestate_;
    73     for( const auto& mapEntry : gamestateQueue )
    74       delete mapEntry.second;
    75     for( const auto& mapEntryPeer : peerMap_ )
    76     {
    77       for( const auto& mapEntryGamestate : mapEntryPeer.second.gamestates )
    78         delete mapEntryGamestate.second;
    79     }
    80 //     this->trafficControl_->destroy();
    81 //     delete this->threadMutex_;
    82 //     delete this->threadPool_;
    83   }
    84 
    85   bool GamestateManager::update(){
    86 //     cleanup();
    87     return getSnapshot();
     66    if(this->currentGamestate_)
     67    {
     68      delete this->currentGamestate_;
     69      this->currentGamestate_ = nullptr;
     70    }
     71
     72    for(const auto& gsPair : this->gamestateQueue)
     73    {
     74      delete gsPair.second;
     75    }
     76
     77    for(const auto& peerPair : this->peerMap_)
     78    {
     79      for(const auto& gsPair : peerPair.second.gamestates)
     80      {
     81        delete gsPair.second;
     82      }
     83    }
     84  }
     85
     86  bool GamestateManager::update()
     87  {
     88    return this->getSnapshot();
    8889  }
    8990
     
    9192  {
    9293    assert(gs);
    93     std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
    94     if(it!=gamestateQueue.end())
     94    // Search the queue for a gamestate for the client
     95    std::map<unsigned int, packet::Gamestate*>::iterator it = this->gamestateQueue.find(clientID);
     96    if(it != this->gamestateQueue.end())
    9597    {
    9698      // delete obsolete gamestate
    9799      delete it->second;
    98100    }
    99     gamestateQueue[clientID] = gs;
     101    // update the client's gamestate
     102    this->gamestateQueue[clientID] = gs;
     103
    100104    return true;
    101105  }
    102106
     107  /**
     108   * Process the queued gamestates.
     109   */
    103110  bool GamestateManager::processGamestates()
    104111  {
    105     if( this->gamestateQueue.empty() )
     112    // Queue is empty, nothing to do
     113    if(this->gamestateQueue.empty())
     114    {
    106115        return true;
     116    }
     117
    107118    // now push only the most recent gamestates we received (ignore obsolete ones)
    108     for(const auto& mapEntry : gamestateQueue)
    109     {
    110       OrxVerify(processGamestate(mapEntry.second), "ERROR: could not process Gamestate");
    111       sendAck( mapEntry.second->getID(), mapEntry.second->getPeerID() );
    112       delete mapEntry.second;
     119    for(const auto& gsPair : this->gamestateQueue)
     120    {
     121      OrxVerify(this->processGamestate(gsPair.second), "ERROR: could not process Gamestate");
     122      this->sendAck(gsPair.second->getID(), gsPair.second->getPeerID());
     123      delete gsPair.second;
    113124    }
    114125    // now clear the queue
    115     gamestateQueue.clear();
     126    this->gamestateQueue.clear();
     127
    116128    //and call all queued callbacks
    117129    NetworkCallbackManager::callCallbacks();
     130
    118131    return true;
    119132  }
    120133 
     134  /**
     135   * Send Acknowledgement packet.
     136   * @param gamestateId The gamestate ID we want to acknowledge
     137   * @param peerID The ID of the peer we want to send the Acknowledgement to
     138   */
    121139  bool GamestateManager::sendAck(unsigned int gamestateID, uint32_t peerID)
    122140  {
    123     assert( gamestateID != ACKID_NACK );
     141    assert(gamestateID != ACKID_NACK);
    124142    packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, peerID);
    125     if( !this->sendPacket(ack))
     143    if(!this->sendPacket(ack))
    126144    {
    127145      orxout(internal_warning, context::network) << "could not ack gamestate: " << gamestateID << endl;
     
    135153  }
    136154
    137 
    138   bool GamestateManager::getSnapshot(){
    139     if ( currentGamestate_ != nullptr )
    140       delete currentGamestate_;
     155  /**
     156   * Update the current gamestate.
     157   */
     158  bool GamestateManager::getSnapshot()
     159  {
     160    // Delete current gamestate
     161    if (this->currentGamestate_)
     162    {
     163      delete this->currentGamestate_;
     164      this->currentGamestate_ = nullptr;
     165    }
     166
    141167    uint8_t gsMode;
    142     if( GameMode::isMaster() )
     168    if(GameMode::isMaster())
     169    {
    143170      gsMode = packet::GAMESTATE_MODE_SERVER;
    144     else
     171    }
     172    else
     173    {
    145174      gsMode = packet::GAMESTATE_MODE_CLIENT;
     175    }
     176
    146177    uint32_t newID;
    147     if( GameMode::isMaster() )
    148       newID = ++id_;
    149     else
    150     {
    151       assert(peerMap_.size()!=0);
    152       newID = peerMap_[NETWORK_PEER_ID_SERVER].lastReceivedGamestateID;
    153       if( newID == GAMESTATEID_INITIAL )
     178    if(GameMode::isMaster())
     179    {
     180      newID = ++this->id_;
     181    }
     182    else
     183    {
     184      assert(this->peerMap_.size() != 0);
     185      newID = this->peerMap_[NETWORK_PEER_ID_SERVER].lastReceivedGamestateID;
     186      if(newID == GAMESTATEID_INITIAL)
    154187      {
    155188        return false;
     
    157190    }
    158191   
    159     currentGamestate_ = new packet::Gamestate();
    160    
    161     if(!currentGamestate_->collectData(newID, gsMode))
    162     { //we have no data to send
    163       delete currentGamestate_;
    164       currentGamestate_=nullptr;
     192    // Create a new gamestate
     193    this->currentGamestate_ = new packet::Gamestate();
     194    if(!this->currentGamestate_->collectData(newID, gsMode))
     195    {
     196      // we have no data to send
     197      delete this->currentGamestate_;
     198      this->currentGamestate_ = nullptr;
    165199      return false;
    166200    }
     201
    167202    return true;
    168203  }
    169204
     205  /**
     206   * Return a vector with the gamestates of all peers.
     207   */
    170208  std::vector<packet::Gamestate*> GamestateManager::getGamestates()
    171209  {
    172     if(!currentGamestate_)
     210    // Current gamestate is empty
     211    if(!this->currentGamestate_){
    173212      return std::vector<packet::Gamestate*>();
     213    }
     214
    174215    std::vector<packet::Gamestate*> peerGamestates;
    175    
    176     for( const auto& mapEntry : peerMap_ )
    177     {
    178       if( !mapEntry.second.isSynched )
     216    for(const auto& mapEntry : this->peerMap_)
     217    {
     218      if(!mapEntry.second.isSynched)
    179219      {
    180220        orxout(verbose_more, context::network) << "Server: not sending gamestate" << endl;
     
    198238      peerGamestates.push_back(nullptr);  // insert an empty gamestate* to be changed
    199239      finishGamestate( peerID, peerGamestates.back(), baseGamestate, currentGamestate_ );
    200       if( peerGamestates.back()==nullptr )
     240      if(peerGamestates.back() == nullptr)
     241      {
    201242        // nothing to send to remove pointer from vector
    202243        peerGamestates.pop_back();
    203       //FunctorMember<GamestateManager>* functor =
    204 //       ExecutorMember<GamestateManager>* executor = createExecutor( createFunctor(&GamestateManager::finishGamestate, this) );
    205 //       executor->setDefaultValues( cid, &clientGamestates.back(), client, currentGamestate_ );
    206 //       (*static_cast<Executor*>(executor))();
    207 //       this->threadPool_->passFunction( executor, true );
    208 //       (*functor)( cid, &(clientGamestates.back()), client, currentGamestate_ );
    209     }
    210 
    211 //     threadPool_->synchronise();
     244      }
     245    }
    212246
    213247    return peerGamestates;
     
    215249
    216250
    217   void GamestateManager::finishGamestate( unsigned int peerID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) {
    218     //why are we searching the same client's gamestate id as we searched in
    219     //Server::sendGameState?
     251  void GamestateManager::finishGamestate(unsigned int peerID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate)
     252  {
    220253    // save the (undiffed) gamestate in the clients gamestate map
    221     //chose wheather the next gamestate is the first or not
    222 
    223 //     packet::Gamestate *gs = gamestate->doSelection(clientID, 20000);
    224 //       packet::Gamestate* gs = new packet::Gamestate(*gamestate);
    225 //     packet::Gamestate* gs = gamestate;
     254    // choose whether the next gamestate is the first or not
     255
     256    // Create a copy of the gamestate
    226257    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
    227 //     packet::Gamestate *gs = new packet::Gamestate();
    228 //     gs->collectData( id_, 0x1 );
    229 //     this->threadMutex_->lock();
    230     peerMap_[peerID].gamestates[gamestate->getID()]=gs;
    231 //     this->threadMutex_->unlock();
     258    this->peerMap_[peerID].gamestates[gamestate->getID()] = gs;
     259
     260    // Start the clock
    232261    Clock clock;
    233262    clock.capture();
     
    236265    {
    237266      packet::Gamestate *diffed1 = gs->diffVariables(base);
    238       if( diffed1->getDataSize() == 0 )
     267      if(diffed1->getDataSize() == 0)
    239268      {
    240269        delete diffed1;
     
    249278    }
    250279
    251 
    252 //     OrxVerify(gs->compressData(), "");
     280    // Stop the clock
    253281    clock.capture();
    254282    orxout(verbose_more, context::network) << "diff and compress time: " << clock.getDeltaTime() << endl;
    255 //     orxout(verbose_more, context::network) << "sending gamestate with id " << gs->getID();
    256 //     if(gamestate->isDiffed())
    257 //       orxout(verbose_more, context::network) << " and baseid " << gs->getBaseID() << endl;
    258 //     else
    259 //       orxout(verbose_more, context::network) << endl;
     283
     284
    260285    gs->setPeerID(peerID);
    261286    destgamestate = gs;
     
    263288
    264289
     290  /**
     291   * Acknowledge a received gamestate.
     292   * @param gamestateID The ID of the gamestate to be acknowledged
     293   * @param peerID The ID of the peer to send the Acknowledgement to
     294   */
    265295  bool GamestateManager::ackGamestate(unsigned int gamestateID, unsigned int peerID)
    266296  {
    267 //     ClientInformation *temp = ClientInformation::findClient(peerID);
    268 //     assert(temp);
     297    // Search for the peer in the peer map
    269298    std::map<uint32_t, peerInfo>::iterator it = this->peerMap_.find(peerID);
    270     assert(it!=this->peerMap_.end());
     299    assert(it != this->peerMap_.end());
     300
    271301    unsigned int curid = it->second.lastAckedGamestateID;
    272302
    273303    assert(gamestateID != ACKID_NACK);
    274 //     if(gamestateID == ACKID_NACK){
    275 //       it->second.lastAckedGamestateID = GAMESTATEID_INITIAL;
    276 // //       temp->setGamestateID(GAMESTATEID_INITIAL);
    277 //       // now delete all saved gamestates for this client
    278 //       std::map<uint32_t, packet::Gamestate*>::iterator it2;
    279 //       for(it2 = it->second.gamestates.begin(); it2!=it->second.gamestates.end(); ++it2 ){
    280 //         delete it2->second;
    281 //       }
    282 //       it->second.gamestates.clear();
    283 //       return true;
    284 //     }
    285 
    286 //    assert(curid==GAMESTATEID_INITIAL || curid<=gamestateID); // this line is commented out because acknowledgements are unreliable and may arrive in distorted order
    287     if( gamestateID <= curid && curid != GAMESTATEID_INITIAL )
     304
     305    // The gamestate has already been acknowledged, nothing to do
     306    if(gamestateID <= curid && curid != GAMESTATEID_INITIAL)
     307    {
    288308        return true;
    289 orxout(verbose, context::network) << "acking gamestate " << gamestateID << " for peerID: " << peerID << " curid: " << curid << endl;
     309    }
     310
     311    orxout(verbose, context::network) << "acking gamestate " << gamestateID << " for peerID: " << peerID << " curid: " << curid << endl;
    290312    std::map<uint32_t, packet::Gamestate*>::iterator it2;
    291     for( it2=it->second.gamestates.begin(); it2!=it->second.gamestates.end(); )
    292     {
    293       if( it2->second->getID() < gamestateID )
     313    for (it2 = it->second.gamestates.begin(); it2 != it->second.gamestates.end();)
     314    {
     315      if(it2->second->getID() < gamestateID)
    294316      {
    295317        delete it2->second;
     
    297319      }
    298320      else
     321      {
    299322        ++it2;
     323      }
    300324    }
    301325   
    302 //     std::map<unsigned int, packet::Gamestate*>::iterator it;
    303 //     for(it = gamestateMap_[peerID].begin(); it!=gamestateMap_[peerID].end() && it->first<gamestateID; ){
    304 //       delete it->second;
    305 //       gamestateMap_[peerID].erase(it++);
    306 //     }
     326    // update the last acked gamestate
    307327    it->second.lastAckedGamestateID = gamestateID;
    308 //     temp->setGamestateID(gamestateID);
    309 //     TrafficControl::processAck(peerID, gamestateID);
     328
    310329    return true;
    311330  }
    312331 
     332  /**
     333   * Return the ID of the last received gamestate for a certain peer
     334   * @param peerID The ID of the peer\
     335   */
    313336  uint32_t GamestateManager::getLastReceivedGamestateID(unsigned int peerID)
    314337  {
    315     assert( this->peerMap_.find(peerID)!=this->peerMap_.end() );
    316     if( this->peerMap_.find(peerID) != this->peerMap_.end() )
     338    if(this->peerMap_.find(peerID) != this->peerMap_.end())
     339    {
    317340      return this->peerMap_[peerID].lastReceivedGamestateID;
    318     else
     341    }
     342    else
     343    {
    319344      return GAMESTATEID_INITIAL;
     345    }
    320346  }
    321347 
    322  
     348  /**
     349   * Add a peer to the game.
     350   * @param peerID The ID of the peer to add.
     351   */
    323352  void GamestateManager::addPeer(uint32_t peerID)
    324353  {
    325     assert(peerMap_.find(peerID)==peerMap_.end());
    326     peerMap_[peerID].peerID = peerID;
    327     peerMap_[peerID].lastReceivedGamestateID = GAMESTATEID_INITIAL;
    328     peerMap_[peerID].lastAckedGamestateID = GAMESTATEID_INITIAL;
    329     if( GameMode::isMaster() )
    330       peerMap_[peerID].isSynched = false;
    331     else
    332       peerMap_[peerID].isSynched = true;
    333   }
    334 
     354    // Ensure that the peer doesn't already exist.
     355    assert(this->peerMap_.find(peerID) == this->peerMap_.end());
     356
     357    // Create the peerInfo struct for the peer
     358    this->peerMap_[peerID].peerID = peerID;
     359    this->peerMap_[peerID].lastReceivedGamestateID = GAMESTATEID_INITIAL;
     360    this->peerMap_[peerID].lastAckedGamestateID = GAMESTATEID_INITIAL;
     361    if(GameMode::isMaster())
     362    {
     363      this->peerMap_[peerID].isSynched = false;
     364    }
     365    else
     366    {
     367      this->peerMap_[peerID].isSynched = true;
     368    }
     369  }
     370
     371  /**
     372   * Remove a peer from the game.
     373   * @param peerID The ID of the peer to be removed
     374   */
    335375  void GamestateManager::removePeer(uint32_t peerID)
    336376  {
    337     assert(peerMap_.find(peerID)!=peerMap_.end());
    338     for( const auto& mapEntry : peerMap_[peerID].gamestates )
     377    // Make sure that the peer exists
     378    assert(this->peerMap_.find(peerID) != this->peerMap_.end());
     379
     380    for (const auto& mapEntry : this->peerMap_[peerID].gamestates)
    339381    {
    340382      delete mapEntry.second;
    341383    }
    342     peerMap_.erase(peerMap_.find(peerID));
    343   }
    344 
    345 
    346 //   void GamestateManager::removeClient(ClientInformation* client){
    347 //     assert(client);
    348 //     std::map<unsigned int, std::map<unsigned int, packet::Gamestate*>>::iterator clientMap = gamestateMap_.find(client->getID());
    349 //     // first delete all remained gamestates
    350 //     std::map<unsigned int, packet::Gamestate*>::iterator it;
    351 //     for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
    352 //       delete it->second;
    353 //     // now delete the clients gamestatemap
    354 //     gamestateMap_.erase(clientMap);
    355 //   }
    356 
     384    this->peerMap_.erase(this->peerMap_.find(peerID));
     385  }
     386
     387  /**
     388   * Process an incoming Gamestate packet.
     389   * @param gs Pointer to the incoming Gamestate packet
     390   */
    357391  bool GamestateManager::processGamestate(packet::Gamestate *gs)
    358392  {
     393    // Decompress if necessary
    359394    if(gs->isCompressed())
    360395    {
     
    362397    }
    363398    assert(!gs->isDiffed());
     399
    364400    uint8_t gsMode;
    365     if( GameMode::isMaster() )
     401    if(GameMode::isMaster())
     402    {
    366403      gsMode = packet::GAMESTATE_MODE_SERVER;
    367     else
     404    }
     405    else
     406    {
    368407      gsMode = packet::GAMESTATE_MODE_CLIENT;
    369     if( gs->spreadData(gsMode) )
     408    }
     409
     410    if(gs->spreadData(gsMode))
    370411    {
    371412      this->peerMap_[gs->getPeerID()].lastReceivedGamestateID = gs->getID();
     
    373414    }
    374415    else
     416    {
    375417      return false;
     418    }
    376419  }
    377420
Note: See TracChangeset for help on using the changeset viewer.