Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 7801 for code/trunk/src


Ignore:
Timestamp:
Dec 22, 2010, 7:24:24 PM (14 years ago)
Author:
dafrick
Message:

Merging presentation2 branch back to trunk.

Location:
code/trunk
Files:
69 edited
15 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/GUIManager.cc

    r7709 r7801  
    5959#include "util/Exception.h"
    6060#include "util/OrxAssert.h"
     61#include "ConfigValueIncludes.h"
    6162#include "Core.h"
     63#include "CoreIncludes.h"
    6264#include "GraphicsManager.h"
    6365#include "LuaState.h"
     
    100102
    101103    GUIManager* GUIManager::singletonPtr_s = 0;
     104    /*static*/ const std::string GUIManager::defaultScheme_ = "TaharezGreen";
    102105
    103106    SetConsoleCommand("showGUI", &GUIManager::showGUI).defaultValue(1, false).defaultValue(2, false);
     
    118121        , camera_(NULL)
    119122    {
     123        RegisterRootObject(GUIManager);
     124        this->setConfigValues();
     125
    120126        using namespace CEGUI;
    121127
     
    175181    GUIManager::~GUIManager()
    176182    {
     183    }
     184
     185    void GUIManager::setConfigValues(void)
     186    {
     187        SetConfigValue(guiScheme_, GUIManager::defaultScheme_) .description("Changes the current GUI scheme.") .callback(this, &GUIManager::changedGUIScheme);
     188    }
     189
     190    void GUIManager::changedGUIScheme(void)
     191    {
     192       
    177193    }
    178194
  • code/trunk/src/libraries/core/GUIManager.h

    r7648 r7801  
    4949#include "util/Singleton.h"
    5050#include "input/InputHandler.h"
     51#include "OrxonoxClass.h"
    5152
    5253// Tolua includes (have to be relative to the current directory)
     
    7071    */
    7172    class _CoreExport GUIManager // tolua_export
    72         : public Singleton<GUIManager>, public InputHandler
     73        : public Singleton<GUIManager>, public InputHandler, public OrxonoxClass
    7374    { // tolua_export
    7475        friend class Singleton<GUIManager>;
     
    7677        GUIManager(const std::pair<int, int>& mousePosition);
    7778        ~GUIManager();
     79
     80        void setConfigValues(void);
     81        void changedGUIScheme(void);
    7882
    7983        void preUpdate(const Clock& time);
     
    143147        static GUIManager*                   singletonPtr_s;    //!< Singleton reference to GUIManager
    144148
     149        // The used CEGUI scheme.
     150        static const std::string defaultScheme_;
     151        std::string guiScheme_;
     152
    145153    }; // tolua_export
    146154} // tolua_export
  • code/trunk/src/libraries/network/CMakeLists.txt

    r7490 r7801  
    2828  FunctionCallManager.cc
    2929  GamestateManager.cc
    30   GamestateClient.cc
     30  #GamestateClient.cc
    3131  GamestateHandler.cc
    3232  LANDiscoverable.cc
    3333  LANDiscovery.cc
     34  WANDiscoverable.cc
     35  WANDiscovery.cc
     36  MasterServerComm.cc
    3437  NetworkFunction.cc
    3538  Host.cc
    3639  Server.cc
     40  MasterServer.cc
     41  PeerList.cc
     42  ServerList.cc
    3743  ServerConnection.cc
    3844  TrafficControl.cc
     
    4854  FunctionCall.h
    4955  FunctionCallManager.h
    50   GamestateClient.h
     56  #GamestateClient.h
    5157  GamestateHandler.h
    5258  GamestateManager.h
     
    5460  LANDiscoverable.h
    5561  LANDiscovery.h
     62  WANDiscoverable.h
     63  WANDiscovery.h
     64  MasterServerComm.h
    5665  NetworkFunction.h
    5766  NetworkPrecompiledHeaders.h
    5867  NetworkPrereqs.h
    5968  Server.h
     69  MasterServer.h
     70  PeerList.h
     71  ServerList.h
    6072  ServerConnection.h
    6173  TrafficControl.h
     
    6981    Client.h
    7082    LANDiscovery.h
     83    WANDiscovery.h
    7184  PCH_FILE
    7285    NetworkPrecompiledHeaders.h
  • code/trunk/src/libraries/network/Client.cc

    r7495 r7801  
    6464  */
    6565  Client::Client():
    66       gamestate(0),
    6766      isSynched_(false),
    6867      gameStateFailure_(false),
     
    8584  {
    8685    Synchronisable::setClient(true);
    87     this->gamestate = new GamestateClient();
    8886    if( ClientConnection::establishConnection() )
    8987    {
    9088      Host::setActive(true);
     89      GamestateManager::addPeer(NETWORK_PEER_ID_SERVER);
    9190      return true;
    9291    }
     
    101100  bool Client::closeConnection()
    102101  {
    103     assert(this->gamestate);
    104     delete this->gamestate;
    105     this->gamestate = 0;
    106102    Host::setActive(false);
     103    GamestateManager::removePeer(NETWORK_PEER_ID_SERVER);
    107104    return ClientConnection::closeConnection();
    108105  }
     
    114111  }
    115112
    116   bool Client::queuePacket(ENetPacket *packet, int clientID)
    117   {
    118     bool b = ClientConnection::addPacket(packet);
    119     assert(b);
    120     return b;
     113  void Client::queuePacket(ENetPacket *packet, int clientID, uint8_t channelID)
     114  {
     115    ClientConnection::addPacket(packet, channelID);
    121116  }
    122117
     
    140135  {
    141136    packet::Chat *m = new packet::Chat(message, Host::getPlayerID());
    142     return m->send();
     137    return m->send(static_cast<Host*>(this));
    143138  }
    144139
     
    159154      {
    160155        COUT(4) << "popping partial gamestate: " << std::endl;
    161         packet::Gamestate *gs = gamestate->getGamestate();
     156//         packet::Gamestate *gs = GamestateClient::getGamestate();
     157        GamestateManager::update();
     158        std::vector<packet::Gamestate*> gamestates = GamestateManager::getGamestates();
     159        std::vector<packet::Gamestate*>::iterator it;
     160        for( it = gamestates.begin(); it != gamestates.end(); ++it )
     161        {
     162          (*it)->send( static_cast<Host*>(this) );
     163        }
    162164        //assert(gs); <--- there might be the case that no data has to be sent, so its commented out now
    163         if(gs){
    164           COUT(4) << "client tick: sending gs " << gs << std::endl;
    165           if( !gs->send() )
    166             COUT(3) << "Problem adding partial gamestate to queue" << std::endl;
    167         // gs gets automatically deleted by enet callback
    168         }
    169         FunctionCallManager::sendCalls();
     165//         if(gs){
     166//           COUT(4) << "client tick: sending gs " << gs << std::endl;
     167//           if( !gs->send() )
     168//             COUT(2) << "Problem adding partial gamestate to queue" << std::endl;
     169//         // gs gets automatically deleted by enet callback
     170//         }
     171        FunctionCallManager::sendCalls(static_cast<Host*>(this));
    170172      }
    171173    }
    172     sendPackets(); // flush the enet queue
     174//     sendPackets(); // flush the enet queue
    173175
    174176    Connection::processQueue();
    175     if(gamestate->processGamestates())
     177    if(GamestateManager::processGamestates())
    176178    {
    177179      FunctionCallManager::processBufferedFunctionCalls();
     
    179181        isSynched_=true;
    180182    }
    181     gamestate->cleanup();
    182     Connection::sendPackets();
     183//     GamestateManager::cleanup();;
     184//     Connection::sendPackets();
    183185
    184186    return;
     
    200202    Game::getInstance().popState();
    201203  }
     204 
     205  void Client::processPacket(packet::Packet* packet)
     206  {
     207    if( packet->isReliable() )
     208    {
     209      if( this->getLastProcessedGamestateID(packet->getPeerID()) >= packet->getRequiredGamestateID() )
     210        packet->process(static_cast<Host*>(this));
     211      else
     212        this->packetQueue_.push_back(packet);
     213    }
     214    else
     215      packet->process(static_cast<Host*>(this));
     216  }
     217
    202218
    203219
  • code/trunk/src/libraries/network/Client.h

    r7163 r7801  
    4545
    4646#include <string>
     47#include <deque>
    4748
    4849#include "util/UtilPrereqs.h"
    4950#include "util/Singleton.h"
    5051#include "ClientConnection.h"
    51 #include "GamestateClient.h"
     52// #include "GamestateClient.h"
    5253#include "Host.h"
    5354#include "LANDiscovery.h"
     
    7879    void setDestination( const std::string& serverAddress, unsigned int port ); // tolua_export
    7980    bool closeConnection();
    80     bool queuePacket(ENetPacket *packet, int clientID);
     81    void queuePacket(ENetPacket* packet, int clientID, uint8_t channelID);
     82    virtual bool sendPacket( packet::Packet* packet ){ return packet->send( static_cast<Host*>(this) ); }
    8183    bool processChat(const std::string& message, unsigned int playerID);
    8284    virtual bool chat(const std::string& message);
     
    9092    Client(const Client& copy); // not used
    9193    virtual bool isServer_(){return false;}
     94    void processPacket(packet::Packet* packet);
    9295
    9396    static Client* singletonPtr_s;
    94     GamestateClient* gamestate;
    9597    bool isSynched_;
     98    std::deque<packet::Packet*> packetQueue_;
    9699
    97100    bool gameStateFailure_;
  • code/trunk/src/libraries/network/ClientConnection.cc

    r7459 r7801  
    3939  const unsigned int NETWORK_CLIENT_CONNECTION_TIMEOUT = 3000; //millisecs
    4040  const unsigned int NETWORK_CLIENT_MAX_CONNECTIONS = 1;
    41   const unsigned int NETWORK_CLIENT_CHANNELS = 1;
    4241
    4342
     
    7170    ENetEvent event;
    7271
    73     this->host_ = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, 0, 0, 0);
     72    // create host
     73    this->host_ = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, NETWORK_CHANNEL_COUNT, 0, 0);
     74   
    7475    if ( this->host_ == NULL )
    7576    {
     
    7879      return false;
    7980    }
     81   
     82    // enable compression
     83    this->enableCompression();
     84   
    8085    assert( this->host_->socket4 != ENET_SOCKET_NULL || this->host_->socket6 != ENET_SOCKET_NULL );
    8186    if (this->host_->socket4 == ENET_SOCKET_NULL)
     
    8691        COUT(3) << "Info: Using IPv4 and IPv6 Sockets." << std::endl;
    8792
    88     this->server_ = enet_host_connect(this->host_, serverAddress_, NETWORK_CLIENT_CHANNELS, 0);
     93    this->server_ = enet_host_connect(this->host_, serverAddress_, NETWORK_CHANNEL_COUNT, 0);
    8994    if ( this->server_==NULL )
    9095    {
     
    99104      {
    100105        this->established_=true;
     106        Connection::startCommunicationThread();
    101107        return true;
    102108      }
     
    112118      return true;
    113119    this->established_ = false;
     120    Connection::stopCommunicationThread();
    114121    enet_peer_disconnect(this->server_, 0);
    115122    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++)
     
    138145
    139146
    140   bool ClientConnection::addPacket(ENetPacket *packet) {
     147  void ClientConnection::addPacket(ENetPacket *packet, uint8_t channelID) {
    141148    assert( this->server_ );
    142149    assert( packet );
    143     return Connection::addPacket( packet, this->server_ );
     150    return Connection::addPacket( packet, this->server_, channelID );
    144151  }
    145152
     
    153160    COUT(1) << "Received disconnect Packet from Server!" << endl;
    154161        // server closed the connection
     162    this->stopCommunicationThread();
    155163    this->connectionClosed();
    156164  }
  • code/trunk/src/libraries/network/ClientConnection.h

    r6417 r7801  
    4444    void setPort( unsigned int port );
    4545
    46     ENetEvent *getEvent();
     46//     ENetEvent *getEvent();
    4747    // check wheter the packet queue is empty
    48     bool queueEmpty();
     48//     bool queueEmpty();
    4949    // create a new listener thread
    5050    virtual bool establishConnection();
    5151    virtual bool closeConnection();
    5252    // add a packet to queue for the server
    53     bool addPacket(ENetPacket *packet);
     53    void addPacket(ENetPacket *packet, uint8_t channelID);
    5454    inline bool isConnected(){ return this->established_; }
    5555  protected:
  • code/trunk/src/libraries/network/ClientInformation.cc

    r7459 r7801  
    5656    preve=0;
    5757    nexte=0;
    58     partialGamestateID_=GAMESTATEID_INITIAL-1;
    5958    synched_=false;
    6059  }
     
    133132  }
    134133
    135   bool ClientInformation::setPartialGamestateID(int id){
    136     if(!this)
    137       return false;
    138     partialGamestateID_=id;
    139     return true;
    140   }
    141 
    142134  unsigned int ClientInformation::getID() {
    143135    if(!this)
     
    154146  }
    155147
    156   int ClientInformation::getFailures(){
    157     return failures_;
    158   }
    159   void ClientInformation::addFailure(){
    160     failures_++;
    161   }
    162   void ClientInformation::resetFailures(){
    163     failures_=0;
    164   }
    165 
    166148  uint32_t ClientInformation::getRTT(){
    167149    return this->peer_->roundTripTime;
     
    175157    if(this)
    176158      return gamestateID_;
    177     else
    178       return static_cast<unsigned int>(-1);
    179   }
    180 
    181   unsigned int ClientInformation::getPartialGamestateID() {
    182     if(this)
    183       return partialGamestateID_;
    184159    else
    185160      return static_cast<unsigned int>(-1);
  • code/trunk/src/libraries/network/ClientInformation.h

    r5781 r7801  
    6666    bool setPeer(ENetPeer *peer);
    6767    bool setGamestateID(int id);
    68     bool setPartialGamestateID(int id);
    6968    inline void setShipID(unsigned int id){ShipID_=id;}
    7069
     
    7372    unsigned int getID();
    7473    unsigned int getGamestateID();
    75     unsigned int getPartialGamestateID();
    7674    ENetPeer *getPeer();
    7775
    78     int getFailures();
    79     void addFailure();
    80     void resetFailures();
    8176    uint32_t getRTT();
    8277    double getPacketLoss();
     
    106101    unsigned int clientID_;
    107102    unsigned int gamestateID_;
    108     unsigned int partialGamestateID_;
    109103    unsigned int ShipID_;   // this is the unique objectID
    110104    bool synched_;
    111     unsigned short failures_;
    112105
    113106  };
  • code/trunk/src/libraries/network/Connection.cc

    r7163 r7801  
    3030
    3131#include <cassert>
     32#include <deque>
    3233#define WIN32_LEAN_AND_MEAN
    3334#include <enet/enet.h>
     35#include <boost/thread.hpp>
     36#include <boost/thread/mutex.hpp>
     37#include <boost/date_time.hpp>
     38
    3439#include "packet/Packet.h"
    3540
    3641namespace orxonox
    3742{
    38 //   Connection *Connection::instance_=0;
     43  const boost::posix_time::millisec NETWORK_COMMUNICATION_THREAD_WAIT_TIME(20);
    3944
    4045  Connection::Connection():
    41     host_(0)
    42   {
    43 //     assert(instance_==0);
    44 //     Connection::instance_=this;
     46    host_(0), bCommunicationThreadRunning_(false)
     47  {
    4548    enet_initialize();
    4649    atexit(enet_deinitialize);
    47   }
    48 
    49   Connection::~Connection(){
    50 //     Connection::instance_=0;
    51   }
    52 
    53   int Connection::service(ENetEvent* event) {
    54     return enet_host_service( this->host_, event, NETWORK_WAIT_TIMEOUT );
    55   }
    56 
    57   void Connection::disconnectPeer(ENetPeer *peer) {
    58     enet_peer_disconnect(peer, 0);
    59   }
    60 
    61   bool Connection::addPacket(ENetPacket *packet, ENetPeer *peer) {
    62     if(enet_peer_send(peer, NETWORK_DEFAULT_CHANNEL, packet)!=0)
    63       return false;
    64     else
    65       return true;
    66   }
    67 
    68   bool Connection::sendPackets() {
    69     if ( /*!Connection::instance_ || */this->host_==NULL )
    70       return false;
    71     enet_host_flush(this->host_);
    72     return true;
    73   }
    74 
    75   void Connection::processQueue() {
     50    this->incomingEventsMutex_ = new boost::mutex;
     51    this->outgoingEventsMutex_ = new boost::mutex;
     52  }
     53
     54  Connection::~Connection()
     55  {
     56    delete this->incomingEventsMutex_;
     57    delete this->outgoingEventsMutex_;
     58  }
     59
     60  void Connection::startCommunicationThread()
     61  {
     62    this->bCommunicationThreadRunning_ = true;
     63    this->communicationThread_ = new boost::thread(&Connection::communicationThread, this);
     64  }
     65 
     66  void Connection::stopCommunicationThread()
     67  {
     68    this->bCommunicationThreadRunning_ = false;
     69    if( !this->communicationThread_->timed_join(NETWORK_COMMUNICATION_THREAD_WAIT_TIME) )
     70    {
     71      // force thread to stop
     72      this->communicationThread_->interrupt();
     73    }
     74    delete this->communicationThread_;
     75  }
     76
     77
     78//   int Connection::service(ENetEvent* event) {
     79//     return enet_host_service( this->host_, event, NETWORK_WAIT_TIMEOUT );
     80//   }
     81
     82  void Connection::disconnectPeer(ENetPeer *peer)
     83  {
     84    assert(peer);
     85    outgoingEvent outEvent = { peer, outgoingEventType::disconnectPeer, (ENetPacket*)10, 15 };
     86   
     87    this->outgoingEventsMutex_->lock();
     88    this->outgoingEvents_.push_back(outEvent);
     89    this->outgoingEventsMutex_->unlock();
     90  }
     91
     92  void Connection::addPacket(ENetPacket *packet, ENetPeer *peer, uint8_t channelID)
     93  {
     94    assert(peer);
     95    outgoingEvent outEvent = { peer, outgoingEventType::sendPacket, packet, channelID };
     96   
     97    this->outgoingEventsMutex_->lock();
     98    this->outgoingEvents_.push_back(outEvent);
     99    this->outgoingEventsMutex_->unlock();
     100  }
     101 
     102  void Connection::broadcastPacket(ENetPacket* packet, uint8_t channelID)
     103  {
     104    outgoingEvent outEvent = { (ENetPeer*)15, outgoingEventType::broadcastPacket, packet, channelID };
     105   
     106    this->outgoingEventsMutex_->lock();
     107    this->outgoingEvents_.push_back(outEvent);
     108    this->outgoingEventsMutex_->unlock();
     109  }
     110
     111 
     112  void Connection::communicationThread()
     113  {
    76114    ENetEvent event;
    77 
    78     assert(this->host_);
    79 
    80     while( enet_host_service( this->host_, &event, NETWORK_WAIT_TIMEOUT ) > 0 )
     115   
     116    while( bCommunicationThreadRunning_ )
    81117    {
    82       switch(event.type){
     118      // Receive all pending incoming Events (such as packets, connects and disconnects)
     119      while( enet_host_check_events( this->host_, &event ) > 0 )
     120      {
     121//         COUT(0) << "incoming event" << endl;
     122        // received an event
     123        this->incomingEventsMutex_->lock();
     124        this->incomingEvents_.push_back(event);
     125        this->incomingEventsMutex_->unlock();
     126      }
     127     
     128      // Send all waiting outgoing packets
     129      this->outgoingEventsMutex_->lock();
     130      uint32_t outgoingEventsCount = this->outgoingEvents_.size();
     131      this->outgoingEventsMutex_->unlock();
     132      while( outgoingEventsCount > 0 )
     133      {
     134//         COUT(0) << "outgoing event" << endl;
     135        this->outgoingEventsMutex_->lock();
     136        outgoingEvent outEvent = this->outgoingEvents_.front();
     137        this->outgoingEvents_.pop_front();
     138        this->outgoingEventsMutex_->unlock();
     139       
     140        switch( outEvent.type )
     141        {
     142          case outgoingEventType::sendPacket:
     143            enet_peer_send( outEvent.peer, outEvent.channelID, outEvent.packet );
     144            break;
     145          case outgoingEventType::disconnectPeer:
     146            enet_peer_disconnect(outEvent.peer, 0);
     147            break;
     148          case outgoingEventType::broadcastPacket:
     149            enet_host_broadcast( this->host_, outEvent.channelID, outEvent.packet );
     150            break;
     151          default:
     152            assert(0);
     153        }
     154        this->outgoingEventsMutex_->lock();
     155        outgoingEventsCount = this->outgoingEvents_.size();
     156        this->outgoingEventsMutex_->unlock();
     157      }
     158     
     159      // Wait for incoming events (at most NETWORK_WAIT_TIMEOUT ms)
     160      if( enet_host_service( this->host_, &event, NETWORK_WAIT_TIMEOUT ) > 0 )
     161      {
     162//         COUT(0) << "incoming event after wait" << endl;
     163        //received an event
     164        this->incomingEventsMutex_->lock();
     165        this->incomingEvents_.push_back(event);
     166        this->incomingEventsMutex_->unlock();
     167      }
     168    }
     169  }
     170
     171  void Connection::processQueue()
     172  {
     173    ENetEvent event;
     174
     175    this->incomingEventsMutex_->lock();
     176    uint32_t incomingEventsCount = this->incomingEvents_.size();
     177    this->incomingEventsMutex_->unlock();
     178    while( incomingEventsCount > 0 )
     179    {
     180      packet::Packet* p;
     181      this->incomingEventsMutex_->lock();
     182      event = this->incomingEvents_.front();
     183      this->incomingEvents_.pop_front();
     184      this->incomingEventsMutex_->unlock();
     185     
     186      switch(event.type)
     187      {
    83188        // log handling ================
    84189        case ENET_EVENT_TYPE_CONNECT:
     
    89194          break;
    90195        case ENET_EVENT_TYPE_RECEIVE:
    91           processPacket( &event );
     196//           COUT(0) << "ENET_EVENT_TYPE_RECEIVE" << endl;
     197          p = createPacket( &event );
     198          processPacket(p);
    92199          break;
    93200        case ENET_EVENT_TYPE_NONE:
    94201          break;
    95202      }
     203     
     204      this->incomingEventsMutex_->lock();
     205      incomingEventsCount = this->incomingEvents_.size();
     206      this->incomingEventsMutex_->unlock();
    96207    }
    97208  }
    98209
    99   bool Connection::processPacket(ENetEvent* event) {
     210  packet::Packet* Connection::createPacket(ENetEvent* event)
     211  {
    100212    packet::Packet *p = packet::Packet::createPacket(event->packet, event->peer);
    101     return p->process();
    102   }
     213    return p;
     214//     return p->process();
     215  }
     216 
     217  void Connection::enableCompression()
     218  {
     219    enet_host_compress_with_range_coder( this->host_ );
     220  }
     221
    103222
    104223}
  • code/trunk/src/libraries/network/Connection.h

    r7163 r7801  
    4343#include "NetworkPrereqs.h"
    4444
     45#include <deque>
     46#include <enet/enet.h>
     47
     48namespace boost
     49{
     50  class thread;
     51  class mutex;
     52}
     53
    4554namespace orxonox
    4655{
    47     const unsigned int NETWORK_PORT = 55556;
    48     const unsigned int NETWORK_MAX_CONNECTIONS = 50;
    49     const unsigned int NETWORK_WAIT_TIMEOUT = 0;
    50     const unsigned int NETWORK_DEFAULT_CHANNEL = 0;
    51     const unsigned int NETWORK_MAX_QUEUE_PROCESS_TIME = 5;
    52 
    53   class _NetworkExport Connection{
     56  const unsigned int NETWORK_PORT                   = 55556;
     57  const unsigned int NETWORK_MAX_CONNECTIONS        = 50;
     58  const unsigned int NETWORK_WAIT_TIMEOUT           = 1;
     59  const unsigned int NETWORK_MAX_QUEUE_PROCESS_TIME = 5;
     60 
     61  namespace outgoingEventType
     62  {
     63    enum Value
     64    {
     65      sendPacket      = 1,
     66      disconnectPeer  = 2,
     67      broadcastPacket = 3
     68    };
     69   
     70  }
     71 
     72  struct _NetworkExport outgoingEvent
     73  {
     74    ENetPeer*                 peer;
     75    outgoingEventType::Value  type;
     76    ENetPacket*               packet;
     77    ENetChannelID             channelID;
     78  };
     79 
     80  class _NetworkExport Connection
     81  {
    5482  public:
    5583    virtual ~Connection();
    5684
    57     static bool addPacket(ENetPacket *packet, ENetPeer *peer);
    58     bool sendPackets();
    59     ENetHost* getHost(){ return this->host_; }
     85    void addPacket(ENetPacket *packet, ENetPeer *peer, uint8_t channelID);
     86    void broadcastPacket(ENetPacket* packet, uint8_t channelID);
     87//     ENetHost* getHost(){ return this->host_; }
    6088
    6189  protected:
     
    6391//     static Connection* getInstance(){ return Connection::instance_; }
    6492
    65     int service(ENetEvent* event);
     93//     int service(ENetEvent* event);
     94    void startCommunicationThread();
     95    void stopCommunicationThread();
     96    void communicationThread();
    6697    virtual void disconnectPeer(ENetPeer *peer);
     98   
     99    void enableCompression();
    67100
    68101    void processQueue();
    69102    virtual void addPeer(ENetEvent* event)=0;
    70103    virtual void removePeer(ENetEvent* event)=0;
    71     virtual bool processPacket(ENetEvent* event);
     104    virtual void processPacket( packet::Packet* packet)=0;
     105    virtual packet::Packet* createPacket(ENetEvent* event);
    72106
    73     ENetHost *host_;
     107    ENetHost*                   host_;
    74108  private:
    75     ENetAddress *bindAddress_;
     109    boost::thread*              communicationThread_;
     110    bool                        bCommunicationThreadRunning_;
     111    ENetAddress*                bindAddress_;
     112    std::deque<ENetEvent>       incomingEvents_;
     113    std::deque<outgoingEvent>   outgoingEvents_;
     114    boost::mutex*               incomingEventsMutex_;
     115    boost::mutex*               outgoingEventsMutex_;
    76116
    77117//     static Connection *instance_;
  • code/trunk/src/libraries/network/FunctionCallManager.cc

    r7495 r7801  
    3030#include "packet/FunctionCalls.h"
    3131#include "core/GameMode.h"
     32#include "GamestateHandler.h"
    3233
    3334namespace orxonox {
    3435
    35 std::map<uint32_t, packet::FunctionCalls*> FunctionCallManager::sClientMap_;
    36 std::vector<FunctionCall> FunctionCallManager::sIncomingFunctionCallBuffer_;
     36std::map<uint32_t, packet::FunctionCalls*> FunctionCallManager::sPeerMap_;
     37std::vector<std::pair<FunctionCall, std::pair<uint32_t, uint32_t> > > FunctionCallManager::sIncomingFunctionCallBuffer_;
    3738
    3839// Static calls
    3940
    40 void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID)
     41void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t peerID)
    4142{
    42   if(sClientMap_.find(clientID)==sClientMap_.end())
     43  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    4344  {
    44     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    45     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     45    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     46    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    4647  }
    47   FunctionCallManager::sClientMap_[clientID]->addCallStatic(functionID);
     48  FunctionCallManager::sPeerMap_[peerID]->addCallStatic(functionID);
    4849}
    49 void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1)
     50void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1)
    5051{
    51   if(sClientMap_.find(clientID)==sClientMap_.end())
     52  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    5253  {
    53     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    54     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     54    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     55    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    5556  }
    56   FunctionCallManager:: sClientMap_[clientID]->addCallStatic(functionID, &mt1);
     57  FunctionCallManager:: sPeerMap_[peerID]->addCallStatic(functionID, &mt1);
    5758}
    58 void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2)
     59void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2)
    5960{
    60   if(sClientMap_.find(clientID)==sClientMap_.end())
     61  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    6162  {
    62     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    63     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     63    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     64    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    6465  }
    65   FunctionCallManager:: sClientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2);
     66  FunctionCallManager:: sPeerMap_[peerID]->addCallStatic(functionID, &mt1, &mt2);
    6667}
    67 void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
     68void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
    6869{
    69   if(sClientMap_.find(clientID)==sClientMap_.end())
     70  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    7071  {
    71     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    72     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     72    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     73    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    7374  }
    74   FunctionCallManager:: sClientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3);
     75  FunctionCallManager:: sPeerMap_[peerID]->addCallStatic(functionID, &mt1, &mt2, &mt3);
    7576}
    76 void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
     77void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
    7778{
    78   if(sClientMap_.find(clientID)==sClientMap_.end())
     79  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    7980  {
    80     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    81     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     81    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     82    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    8283  }
    83   FunctionCallManager:: sClientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4);
     84  FunctionCallManager:: sPeerMap_[peerID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4);
    8485}
    85 void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
     86void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
    8687{
    87   if(sClientMap_.find(clientID)==sClientMap_.end())
     88  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    8889  {
    89     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    90     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     90    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     91    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    9192  }
    92   FunctionCallManager:: sClientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4, &mt5);
     93  FunctionCallManager:: sPeerMap_[peerID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4, &mt5);
    9394}
    9495
     
    9697// MemberCalls
    9798
    98 void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID)
     99void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID)
    99100{
    100   if(sClientMap_.find(clientID)==sClientMap_.end())
     101  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    101102  {
    102     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    103     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     103    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     104    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    104105  }
    105   FunctionCallManager::sClientMap_[clientID]->addCallMember(functionID, objectID);
     106  FunctionCallManager::sPeerMap_[peerID]->addCallMember(functionID, objectID);
    106107}
    107 void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1)
     108void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1)
    108109{
    109   if(sClientMap_.find(clientID)==sClientMap_.end())
     110  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    110111  {
    111     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    112     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     112    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     113    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    113114  }
    114   FunctionCallManager::sClientMap_[clientID]->addCallMember(functionID, objectID, &mt1);
     115  FunctionCallManager::sPeerMap_[peerID]->addCallMember(functionID, objectID, &mt1);
    115116}
    116 void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2)
     117void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2)
    117118{
    118   if(sClientMap_.find(clientID)==sClientMap_.end())
     119  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    119120  {
    120     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    121     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     121    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     122    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    122123  }
    123   FunctionCallManager::sClientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2);
     124  FunctionCallManager::sPeerMap_[peerID]->addCallMember(functionID, objectID, &mt1, &mt2);
    124125}
    125 void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
     126void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
    126127{
    127   if(sClientMap_.find(clientID)==sClientMap_.end())
     128  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    128129  {
    129     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    130     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     130    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     131    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    131132  }
    132   FunctionCallManager::sClientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3);
     133  FunctionCallManager::sPeerMap_[peerID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3);
    133134}
    134 void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
     135void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
    135136{
    136   if(sClientMap_.find(clientID)==sClientMap_.end())
     137  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    137138  {
    138     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    139     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     139    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     140    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    140141  }
    141   FunctionCallManager::sClientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4);
     142  FunctionCallManager::sPeerMap_[peerID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4);
    142143}
    143 void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
     144void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
    144145{
    145   if(sClientMap_.find(clientID)==sClientMap_.end())
     146  if(sPeerMap_.find(peerID)==sPeerMap_.end())
    146147  {
    147     FunctionCallManager::sClientMap_[clientID] = new packet::FunctionCalls;
    148     FunctionCallManager::sClientMap_[clientID]->setClientID(clientID);
     148    FunctionCallManager::sPeerMap_[peerID] = new packet::FunctionCalls;
     149    FunctionCallManager::sPeerMap_[peerID]->setPeerID(peerID);
    149150  }
    150   FunctionCallManager::sClientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4, &mt5);
     151  FunctionCallManager::sPeerMap_[peerID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4, &mt5);
    151152}
    152153
    153154// Send calls
    154155
    155 void FunctionCallManager::sendCalls()
     156void FunctionCallManager::sendCalls(orxonox::Host* host)
    156157{
    157158  std::map<uint32_t, packet::FunctionCalls*>::iterator it;
    158   for (it = FunctionCallManager::sClientMap_.begin(); it != FunctionCallManager::sClientMap_.end(); ++it )
     159  for (it = FunctionCallManager::sPeerMap_.begin(); it != FunctionCallManager::sPeerMap_.end(); ++it )
    159160  {
    160     assert(!FunctionCallManager::sClientMap_.empty());
    161     it->second->send();
     161    assert(!FunctionCallManager::sPeerMap_.empty());
     162    it->second->send(host);
    162163  }
    163   FunctionCallManager::sClientMap_.clear();
     164  FunctionCallManager::sPeerMap_.clear();
    164165}
    165166
    166 void FunctionCallManager::bufferIncomingFunctionCall(const orxonox::FunctionCall& fctCall)
     167void FunctionCallManager::bufferIncomingFunctionCall(const orxonox::FunctionCall& fctCall, uint32_t minGamestateID, uint32_t peerID)
    167168{
    168   if( !GameMode::isMaster() )
    169     FunctionCallManager::sIncomingFunctionCallBuffer_.push_back( fctCall );
     169  FunctionCallManager::sIncomingFunctionCallBuffer_.push_back( std::make_pair(fctCall, std::make_pair(minGamestateID, peerID)));
    170170}
    171171
    172172void FunctionCallManager::processBufferedFunctionCalls()
    173173{
    174   std::vector<FunctionCall>::iterator it = FunctionCallManager::sIncomingFunctionCallBuffer_.begin();
     174  std::vector<std::pair<FunctionCall, std::pair<uint32_t, uint32_t> > >::iterator it = FunctionCallManager::sIncomingFunctionCallBuffer_.begin();
    175175  while( it!=FunctionCallManager::sIncomingFunctionCallBuffer_.end() )
    176176  {
    177     if( it->execute() )
     177    if( it->first.execute() )
    178178      FunctionCallManager::sIncomingFunctionCallBuffer_.erase(it);
    179179    else
     180    {
    180181      ++it;
     182    }
    181183  }
    182184}
  • code/trunk/src/libraries/network/FunctionCallManager.h

    r7495 r7801  
    3434#include <map>
    3535#include <vector>
     36#include <utility>
    3637#include "util/UtilPrereqs.h"
    3738#include "FunctionCall.h"
     
    4546{
    4647public:
    47   static void addCallStatic(uint32_t functionID, uint32_t clientID);
    48   static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1);
    49   static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2);
    50   static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
    51   static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
    52   static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
     48  static void addCallStatic(uint32_t functionID, uint32_t peerID);
     49  static void addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1);
     50  static void addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2);
     51  static void addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
     52  static void addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
     53  static void addCallStatic(uint32_t functionID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
    5354
    54   static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID);
    55   static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1);
    56   static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2);
    57   static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
    58   static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
    59   static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
     55  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID);
     56  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1);
     57  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2);
     58  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
     59  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
     60  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t peerID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
    6061
    61   static void sendCalls();
     62  static void sendCalls(orxonox::Host* host);
    6263 
    63   static void bufferIncomingFunctionCall( const FunctionCall& fctCall );
     64  static void bufferIncomingFunctionCall( const FunctionCall& fctCall, uint32_t minGamestateID, uint32_t peerID );
    6465  static void processBufferedFunctionCalls();
    6566
    66   static std::map<uint32_t, packet::FunctionCalls*> sClientMap_;
    67   static std::vector<FunctionCall>                  sIncomingFunctionCallBuffer_;
     67  static std::map<uint32_t, packet::FunctionCalls*>                           sPeerMap_;
     68  static std::vector<std::pair<FunctionCall,std::pair<uint32_t, uint32_t> > > sIncomingFunctionCallBuffer_;
    6869protected:
    6970  FunctionCallManager();
  • code/trunk/src/libraries/network/GamestateClient.cc

    r7401 r7801  
    3939namespace orxonox
    4040{
    41   struct _NetworkExport GameStateItem{
     41  struct _NetworkExport GameStateItem
     42  {
    4243    packet::Gamestate *state;
    4344    unsigned int id;
    4445  };
    4546
    46   GamestateClient::GamestateClient() {
     47  GamestateClient::GamestateClient()
     48  {
    4749    COUT(5) << "this: " << this << std::endl;
    48     last_diff_=0;
    49     last_gamestate_=GAMESTATEID_INITIAL-1;
     50    lastAckedGamestateID_=GAMESTATEID_INITIAL-1;
     51    lastProcessedGamestateID_=GAMESTATEID_INITIAL-1;
    5052    tempGamestate_=NULL;
    5153  }
    5254
    53   GamestateClient::~GamestateClient() {
     55  GamestateClient::~GamestateClient()
     56  {
    5457      std::map<unsigned int, packet::Gamestate *>::iterator it;
    5558      for ( it = this->gamestateMap_.begin(); it != this->gamestateMap_.end(); ++it )
     
    5962  }
    6063
    61   bool GamestateClient::ack(unsigned int gamestateID, unsigned int clientID){
     64  bool GamestateClient::ackGamestate(unsigned int gamestateID, unsigned int clientID)
     65  {
    6266    return true;
    6367  }
    6468
    65   bool GamestateClient::add(packet::Gamestate *gs, unsigned int clientID){
    66     if(tempGamestate_!=NULL){
     69  bool GamestateClient::addGamestate(packet::Gamestate *gs, unsigned int clientID)
     70  {
     71    if(tempGamestate_!=NULL)
     72    {
    6773      //delete the obsolete gamestate
    6874      if(tempGamestate_->getID()>gs->getID())
     
    7480  }
    7581
    76   bool GamestateClient::processGamestates(){
     82  bool GamestateClient::processGamestates()
     83  {
    7784    if(tempGamestate_==NULL)
    7885      return false;
     
    8592    NetworkCallbackManager::callCallbacks();
    8693
    87     if (!processed){
     94    if (!processed)
     95    {
     96      assert(0);
    8897      sendAck(0);
    8998      return false;
     
    92101    tempGamestate_=NULL;
    93102    gamestateMap_[processed->getID()]=processed;
     103    lastProcessedGamestateID_ = processed->getID();
    94104    if(isDiffed)
    95       last_diff_ = processed->getBaseID();
     105      lastAckedGamestateID_ = processed->getBaseID();
    96106    id = processed->getID();
    97107    sendAck(id);
     
    105115  * @return iterator pointing to the next object in the list
    106116  */
    107   void GamestateClient::removeObject(ObjectListIterator<Synchronisable> &it) {
     117  void GamestateClient::removeObject(ObjectListIterator<Synchronisable> &it)
     118  {
    108119    ObjectListIterator<Synchronisable> temp=it;
    109120    ++it;
     
    111122  }
    112123
    113   packet::Gamestate *GamestateClient::getGamestate(){
     124  packet::Gamestate *GamestateClient::getGamestate()
     125  {
    114126    packet::Gamestate *gs = new packet::Gamestate();
    115     if(!gs->collectData(0,0x2)){
     127    if(!gs->collectData(this->getLastProcessedGamestateID(NETWORK_PEER_ID_SERVER), 0x2))
     128    {
    116129      delete gs;
    117130      return 0;
     
    120133  }
    121134
    122   void GamestateClient::cleanup(){
     135  void GamestateClient::cleanup()
     136  {
    123137    std::map<unsigned int, packet::Gamestate*>::iterator temp, it = gamestateMap_.begin();
    124     while(it!=gamestateMap_.end()){
    125       if(it->first>=last_diff_)
     138    while(it!=gamestateMap_.end())
     139    {
     140      if(it->first>=lastAckedGamestateID_)
    126141        break;
    127142      // otherwise delete that stuff
     
    133148  }
    134149
    135   void GamestateClient::printGamestateMap(){
     150  void GamestateClient::printGamestateMap()
     151  {
    136152    std::map<unsigned int, packet::Gamestate*>::iterator it;
    137153    COUT(4) << "gamestates: ";
    138     for(it=gamestateMap_.begin(); it!=gamestateMap_.end(); it++){
     154    for(it=gamestateMap_.begin(); it!=gamestateMap_.end(); it++)
     155    {
    139156      COUT(4) << it->first << ':' << it->second << '|';
    140157    }
     
    143160  }
    144161
    145   bool GamestateClient::sendAck(unsigned int gamestateID){
     162  bool GamestateClient::sendAck(unsigned int gamestateID)
     163  {
    146164    packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, 0);
    147     if(!ack->send()){
     165    if(!ack->send())
     166    {
    148167      COUT(3) << "could not ack gamestate: " << gamestateID << std::endl;
    149168      return false;
    150169    }
    151     else{
     170    else
     171    {
    152172      COUT(5) << "acked a gamestate: " << gamestateID << std::endl;
    153173      return true;
     
    155175  }
    156176
    157   packet::Gamestate *GamestateClient::processGamestate(packet::Gamestate *gs){
     177  packet::Gamestate *GamestateClient::processGamestate(packet::Gamestate *gs)
     178  {
    158179    if(gs->isCompressed())
    159180    {
  • code/trunk/src/libraries/network/GamestateClient.h

    r5781 r7801  
    5757    ~GamestateClient();
    5858
    59     bool add(packet::Gamestate *gs, unsigned int clientID);
    60     bool ack(unsigned int gamestateID, unsigned int clientID);
     59    virtual bool      addGamestate(packet::Gamestate *gs, unsigned int clientID);
     60    virtual bool      ackGamestate(unsigned int gamestateID, unsigned int clientID);
     61    virtual uint32_t  getLastProcessedGamestateID(unsigned int clientID=0) { return this->lastProcessedGamestateID_; }
     62    virtual uint32_t  getCurrentGamestateID(){ return this->lastProcessedGamestateID_; }
    6163
    6264    bool processGamestates();
     
    6971    bool sendAck(unsigned int gamestateID);
    7072
    71     unsigned int           last_diff_;
    72     unsigned int           last_gamestate_;
     73    unsigned int           lastAckedGamestateID_;
     74    unsigned int           lastProcessedGamestateID_;
    7375    std::map<unsigned int, packet::Gamestate *> gamestateMap_;
    7476    packet::Gamestate *tempGamestate_; // we save the received gamestates here during processQueue
  • code/trunk/src/libraries/network/GamestateHandler.cc

    r6417 r7801  
    3232namespace orxonox {
    3333
    34 GamestateHandler *GamestateHandler::instance_=0;
     34// GamestateHandler *GamestateHandler::instance_=0;
    3535
    3636GamestateHandler::GamestateHandler()
    3737{
    38   assert(instance_==0);
    39   instance_=this;
    4038}
    4139
     
    4341GamestateHandler::~GamestateHandler()
    4442{
    45   instance_=0;
    4643}
    4744
  • code/trunk/src/libraries/network/GamestateHandler.h

    r6073 r7801  
    3232#include "NetworkPrereqs.h"
    3333
     34#include <cassert>
     35
    3436namespace orxonox {
    3537
     
    3739    @author Oliver Scheuss
    3840*/
    39 class _NetworkExport GamestateHandler{
     41class _NetworkExport GamestateHandler
     42{
    4043  private:
    41     virtual bool add(packet::Gamestate *gs, unsigned int clientID)=0;
    42     virtual bool ack(unsigned int gamestateID, unsigned int clientID)=0;
    43 
    44     static GamestateHandler *instance_;
    4544
    4645
     
    5049
    5150  public:
    52     static bool addGamestate(packet::Gamestate *gs, unsigned int clientID){ return instance_->add(gs, clientID); }
    53     static bool ackGamestate(unsigned int gamestateID, unsigned int clientID){ return instance_->ack(gamestateID, clientID); }
     51    virtual bool      addGamestate(packet::Gamestate* gs, unsigned int clientID) = 0;
     52    virtual bool      ackGamestate(unsigned int gamestateID, unsigned int clientID) = 0;
     53    virtual uint32_t  getLastProcessedGamestateID( unsigned int clientID )=0;
     54    virtual uint32_t  getCurrentGamestateID()=0;
    5455};
    5556
  • code/trunk/src/libraries/network/GamestateManager.cc

    r7284 r7801  
    4343#include <cassert>
    4444#include <queue>
    45 #include "util/Clock.h"
    4645// #include <boost/thread/mutex.hpp>
    4746
    48 #include "util/Debug.h"
    49 #include "core/ThreadPool.h"
    50 #include "core/command/Executor.h"
    51 #include "ClientInformation.h"
    5247#include "packet/Acknowledgement.h"
    5348#include "packet/Gamestate.h"
    5449#include "synchronisable/NetworkCallbackManager.h"
    55 #include "TrafficControl.h"
     50
     51#include "core/ThreadPool.h"
     52#include "core/command/Executor.h"
     53#include "core/GameMode.h"
     54#include "util/Debug.h"
     55#include "util/Clock.h"
     56// #include "TrafficControl.h"
    5657
    5758namespace orxonox
    5859{
    5960  GamestateManager::GamestateManager() :
    60   reference(0), id_(0)
    61   {
    62     trafficControl_ = new TrafficControl();
     61  currentGamestate_(0), id_(0)
     62  {
     63//     trafficControl_ = new TrafficControl();
    6364//     threadMutex_ = new boost::mutex();
    6465//     threadPool_ = new ThreadPool();
     
    6768  GamestateManager::~GamestateManager()
    6869  {
    69     if( this->reference )
    70         delete this->reference;std::map<unsigned int, packet::Gamestate*>::iterator it;
     70    if( this->currentGamestate_ )
     71        delete this->currentGamestate_;std::map<unsigned int, packet::Gamestate*>::iterator it;
    7172    for( it = gamestateQueue.begin(); it != gamestateQueue.end(); ++it )
    7273      delete it->second;
    73     std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator it1;
    74     std::map<unsigned int, packet::Gamestate*>::iterator it2;
    75     for( it1 = gamestateMap_.begin(); it1 != gamestateMap_.end(); ++it1 )
    76     {
    77       for( it2 = it1->second.begin(); it2 != it1->second.end(); ++it2 )
    78         delete it2->second;
    79     }
    80     this->trafficControl_->destroy();
     74    std::map<uint32_t, peerInfo>::iterator peerIt;
     75    std::map<uint32_t, packet::Gamestate*>::iterator gamestateIt;
     76    for( peerIt = peerMap_.begin(); peerIt != peerMap_.end(); ++peerIt )
     77    {
     78      for( gamestateIt = peerIt->second.gamestates.begin(); gamestateIt != peerIt->second.gamestates.end(); ++gamestateIt )
     79        delete gamestateIt->second;
     80    }
     81//     this->trafficControl_->destroy();
    8182//     delete this->threadMutex_;
    8283//     delete this->threadPool_;
     
    8889  }
    8990
    90   bool GamestateManager::add(packet::Gamestate *gs, unsigned int clientID){
     91  bool GamestateManager::addGamestate(packet::Gamestate *gs, unsigned int clientID)
     92  {
    9193    assert(gs);
    9294    std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
     
    99101  }
    100102
    101   bool GamestateManager::processGamestates(){
     103  bool GamestateManager::processGamestates()
     104  {
    102105    if( this->gamestateQueue.empty() )
    103106        return true;
     
    107110      bool b = processGamestate(it->second);
    108111      assert(b);
     112      sendAck( it->second->getID(), it->second->getPeerID() );
    109113      delete it->second;
    110114    }
     
    115119    return true;
    116120  }
     121 
     122  bool GamestateManager::sendAck(unsigned int gamestateID, uint32_t peerID)
     123  {
     124    packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, peerID);
     125    if( !this->sendPacket(ack))
     126    {
     127      COUT(3) << "could not ack gamestate: " << gamestateID << std::endl;
     128      return false;
     129    }
     130    else
     131    {
     132      COUT(5) << "acked a gamestate: " << gamestateID << std::endl;
     133      return true;
     134    }
     135  }
    117136
    118137
    119138  bool GamestateManager::getSnapshot(){
    120     if ( reference != 0 )
    121       delete reference;
    122     reference = new packet::Gamestate();
    123     if(!reference->collectData(++id_, 0x1)){ //we have no data to send
    124       delete reference;
    125       reference=0;
     139    if ( currentGamestate_ != 0 )
     140      delete currentGamestate_;
     141    currentGamestate_ = new packet::Gamestate();
     142    uint8_t gsMode;
     143    if( GameMode::isMaster() )
     144      gsMode = packet::GAMESTATE_MODE_SERVER;
     145    else
     146      gsMode = packet::GAMESTATE_MODE_CLIENT;
     147    uint32_t newID;
     148    if( GameMode::isMaster() )
     149      newID = ++id_;
     150    else
     151      newID = peerMap_[NETWORK_PEER_ID_SERVER].lastProcessedGamestateID;
     152   
     153    if(!currentGamestate_->collectData(newID, gsMode)){ //we have no data to send
     154      delete currentGamestate_;
     155      currentGamestate_=0;
    126156    }
    127157    return true;
    128158  }
    129159
    130   void GamestateManager::sendGamestates()
    131   {
    132     ClientInformation *temp = ClientInformation::getBegin();
    133     std::queue<packet::Gamestate*> clientGamestates;
    134     while(temp != NULL){
    135       if( !(temp->getSynched()) ){
     160  std::vector<packet::Gamestate*> GamestateManager::getGamestates()
     161  {
     162    if(!currentGamestate_)
     163      return std::vector<packet::Gamestate*>();
     164    std::vector<packet::Gamestate*> peerGamestates;
     165   
     166    std::map<uint32_t, peerInfo>::iterator peerIt;
     167    for( peerIt=peerMap_.begin(); peerIt!=peerMap_.end(); ++peerIt )
     168    {
     169      if( !peerIt->second.isSynched )
     170      {
    136171        COUT(5) << "Server: not sending gamestate" << std::endl;
    137         temp=temp->next();
    138         if(!temp)
    139           break;
    140172        continue;
    141173      }
    142       COUT(4) << "client id: " << temp->getID() << " RTT: " << temp->getRTT() << " loss: " << temp->getPacketLoss() << std::endl;
     174      COUT(4) << "client id: " << peerIt->first << std::endl;
    143175      COUT(5) << "Server: doing gamestate gamestate preparation" << std::endl;
    144       int cid = temp->getID(); //get client id
    145 
    146       unsigned int gID = temp->getGamestateID();
    147       if(!reference)
    148         return;
    149 
    150       packet::Gamestate *client=0;
    151       if(gID != GAMESTATEID_INITIAL){
    152         assert(gamestateMap_.find(cid)!=gamestateMap_.end());
    153         std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateMap_[cid].find(gID);
    154         if(it!=gamestateMap_[cid].end())
    155         {
    156           client = it->second;
    157         }
    158       }
    159 
    160       clientGamestates.push(0);
    161       finishGamestate( cid, clientGamestates.back(), client, reference );
     176      int peerID = peerIt->first; //get client id
     177
     178      unsigned int lastAckedGamestateID = peerIt->second.lastAckedGamestateID;
     179
     180      packet::Gamestate* baseGamestate=0;
     181      if(lastAckedGamestateID != GAMESTATEID_INITIAL)
     182      {
     183        assert(peerMap_.find(peerID)!=peerMap_.end());
     184        std::map<uint32_t, packet::Gamestate*>::iterator it = peerMap_[peerID].gamestates.find(lastAckedGamestateID);
     185        assert(it!=peerMap_[peerID].gamestates.end());
     186        baseGamestate = it->second;
     187      }
     188
     189      peerGamestates.push_back(0);  // insert an empty gamestate* to change
     190      finishGamestate( peerID, peerGamestates.back(), baseGamestate, currentGamestate_ );
     191      if( peerGamestates.back()==0 )
     192        // nothing to send to remove pointer from vector
     193        peerGamestates.pop_back();
    162194      //FunctorMember<GamestateManager>* functor =
    163195//       ExecutorMember<GamestateManager>* executor = createExecutor( createFunctor(&GamestateManager::finishGamestate, this) );
    164 //       executor->setDefaultValues( cid, &clientGamestates.back(), client, reference );
     196//       executor->setDefaultValues( cid, &clientGamestates.back(), client, currentGamestate_ );
    165197//       (*static_cast<Executor*>(executor))();
    166198//       this->threadPool_->passFunction( executor, true );
    167 //       (*functor)( cid, &(clientGamestates.back()), client, reference );
    168 
    169       temp = temp->next();
     199//       (*functor)( cid, &(clientGamestates.back()), client, currentGamestate_ );
    170200    }
    171201
    172202//     threadPool_->synchronise();
    173203
    174     while( !clientGamestates.empty() )
    175     {
    176       if(clientGamestates.front())
    177         clientGamestates.front()->send();
    178       clientGamestates.pop();
    179     }
    180   }
    181 
    182 
    183   void GamestateManager::finishGamestate( unsigned int clientID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) {
     204    return peerGamestates;
     205  }
     206
     207
     208  void GamestateManager::finishGamestate( unsigned int peerID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) {
    184209    //why are we searching the same client's gamestate id as we searched in
    185210    //Server::sendGameState?
     
    194219//     gs->collectData( id_, 0x1 );
    195220//     this->threadMutex_->lock();
    196     gamestateMap_[clientID][gamestate->getID()]=gs;
     221    peerMap_[peerID].gamestates[gamestate->getID()]=gs;
    197222//     this->threadMutex_->unlock();
    198       Clock clock;
    199       clock.capture();
     223    Clock clock;
     224    clock.capture();
    200225
    201226    if(base)
     
    216241
    217242
    218     bool b = gs->compressData();
    219     assert(b);
    220       clock.capture();
    221       COUT(0) << "diff time: " << clock.getDeltaTime() << endl;
     243//     bool b = gs->compressData();
     244//     assert(b);
     245    clock.capture();
     246    COUT(4) << "diff and compress time: " << clock.getDeltaTime() << endl;
    222247//     COUT(5) << "sending gamestate with id " << gs->getID();
    223248//     if(gamestate->isDiffed())
     
    225250//     else
    226251//       COUT(5) << endl;
    227     gs->setClientID(clientID);
     252    gs->setPeerID(peerID);
    228253    destgamestate = gs;
    229254  }
    230255
    231256
    232   bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) {
    233     ClientInformation *temp = ClientInformation::findClient(clientID);
    234     assert(temp);
    235     unsigned int curid = temp->getGamestateID();
     257  bool GamestateManager::ackGamestate(unsigned int gamestateID, unsigned int peerID)
     258  {
     259//     ClientInformation *temp = ClientInformation::findClient(peerID);
     260//     assert(temp);
     261    std::map<uint32_t, peerInfo>::iterator it = this->peerMap_.find(peerID);
     262    assert(it!=this->peerMap_.end());
     263    unsigned int curid = it->second.lastAckedGamestateID;
    236264
    237265    if(gamestateID == ACKID_NACK){
    238       temp->setGamestateID(GAMESTATEID_INITIAL);
     266      it->second.lastAckedGamestateID = GAMESTATEID_INITIAL;
     267//       temp->setGamestateID(GAMESTATEID_INITIAL);
    239268      // now delete all saved gamestates for this client
    240       std::map<unsigned int, packet::Gamestate*>::iterator it;
    241       for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end(); ){
    242         delete it->second;
    243 
    244         gamestateMap_[clientID].erase(it++);
    245       }
     269      std::map<uint32_t, packet::Gamestate*>::iterator it2;
     270      for(it2 = it->second.gamestates.begin(); it2!=it->second.gamestates.end(); ++it2 ){
     271        delete it2->second;
     272      }
     273      it->second.gamestates.clear();
    246274      return true;
    247275    }
    248276
    249     assert(curid==GAMESTATEID_INITIAL || curid<gamestateID);
    250     COUT(5) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
    251     std::map<unsigned int, packet::Gamestate*>::iterator it;
    252     for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; ){
    253       delete it->second;
    254       gamestateMap_[clientID].erase(it++);
    255     }
    256     temp->setGamestateID(gamestateID);
    257     TrafficControl::processAck(clientID, gamestateID);
     277    assert(curid==GAMESTATEID_INITIAL || curid<=gamestateID);
     278    COUT(5) << "acking gamestate " << gamestateID << " for peerID: " << peerID << " curid: " << curid << std::endl;
     279    std::map<uint32_t, packet::Gamestate*>::iterator it2;
     280    for( it2=it->second.gamestates.begin(); it2!=it->second.gamestates.end(); )
     281    {
     282      if( it2->second->getID() < gamestateID )
     283      {
     284        delete it2->second;
     285        it->second.gamestates.erase(it2++);
     286      }
     287      else
     288        ++it2;
     289    }
     290   
     291//     std::map<unsigned int, packet::Gamestate*>::iterator it;
     292//     for(it = gamestateMap_[peerID].begin(); it!=gamestateMap_[peerID].end() && it->first<gamestateID; ){
     293//       delete it->second;
     294//       gamestateMap_[peerID].erase(it++);
     295//     }
     296    it->second.lastAckedGamestateID = gamestateID;
     297//     temp->setGamestateID(gamestateID);
     298//     TrafficControl::processAck(peerID, gamestateID);
    258299    return true;
    259300  }
    260 
    261   void GamestateManager::removeClient(ClientInformation* client){
    262     assert(client);
    263     std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
    264     // first delete all remained gamestates
    265     std::map<unsigned int, packet::Gamestate*>::iterator it;
    266     for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
    267       delete it->second;
    268     // now delete the clients gamestatemap
    269     gamestateMap_.erase(clientMap);
    270   }
    271 
    272   bool GamestateManager::processGamestate(packet::Gamestate *gs){
     301 
     302  uint32_t GamestateManager::getLastProcessedGamestateID(unsigned int peerID)
     303  {
     304    assert( this->peerMap_.find(peerID)!=this->peerMap_.end() );
     305    if( this->peerMap_.find(peerID) != this->peerMap_.end() )
     306      return this->peerMap_[peerID].lastProcessedGamestateID;
     307    else
     308      return GAMESTATEID_INITIAL;
     309  }
     310 
     311 
     312  void GamestateManager::addPeer(uint32_t peerID)
     313  {
     314    assert(peerMap_.find(peerID)==peerMap_.end());
     315    peerMap_[peerID].peerID = peerID;
     316    peerMap_[peerID].lastProcessedGamestateID = GAMESTATEID_INITIAL;
     317    peerMap_[peerID].lastAckedGamestateID = GAMESTATEID_INITIAL;
     318    if( GameMode::isMaster() )
     319      peerMap_[peerID].isSynched = false;
     320    else
     321      peerMap_[peerID].isSynched = true;
     322  }
     323
     324  void GamestateManager::removePeer(uint32_t peerID)
     325  {
     326    assert(peerMap_.find(peerID)!=peerMap_.end());
     327    std::map<uint32_t, packet::Gamestate*>::iterator peerIt;
     328    for( peerIt = peerMap_[peerID].gamestates.begin(); peerIt!=peerMap_[peerID].gamestates.end(); ++peerIt )
     329    {
     330      delete peerIt->second;
     331    }
     332    peerMap_.erase(peerMap_.find(peerID));
     333  }
     334
     335
     336//   void GamestateManager::removeClient(ClientInformation* client){
     337//     assert(client);
     338//     std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
     339//     // first delete all remained gamestates
     340//     std::map<unsigned int, packet::Gamestate*>::iterator it;
     341//     for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
     342//       delete it->second;
     343//     // now delete the clients gamestatemap
     344//     gamestateMap_.erase(clientMap);
     345//   }
     346
     347  bool GamestateManager::processGamestate(packet::Gamestate *gs)
     348  {
    273349    if(gs->isCompressed())
    274350    {
     
    277353    }
    278354    assert(!gs->isDiffed());
    279     return gs->spreadData(0x1);
     355    uint8_t gsMode;
     356    if( GameMode::isMaster() )
     357      gsMode = packet::GAMESTATE_MODE_SERVER;
     358    else
     359      gsMode = packet::GAMESTATE_MODE_CLIENT;
     360    if( gs->spreadData(gsMode) )
     361    {
     362      this->peerMap_[gs->getPeerID()].lastProcessedGamestateID = gs->getID();
     363      return true;
     364    }
     365    else
     366      return false;
    280367  }
    281368
  • code/trunk/src/libraries/network/GamestateManager.h

    r7163 r7801  
    4646#include "GamestateHandler.h"
    4747#include "core/CorePrereqs.h"
     48#include "packet/Gamestate.h"
     49#include <boost/concept_check.hpp>
    4850
    4951namespace orxonox
     
    6668  * @author Oliver Scheuss
    6769  */
    68   class _NetworkExport GamestateManager: public GamestateHandler{
     70  class _NetworkExport GamestateManager: public GamestateHandler
     71  {
     72    struct peerInfo
     73    {
     74      uint32_t  peerID;
     75      uint32_t  lastProcessedGamestateID;
     76      uint32_t  lastAckedGamestateID;
     77      bool      isSynched;
     78      std::map< uint32_t, packet::Gamestate* > gamestates;
     79    };
     80   
    6981  public:
     82   
    7083    GamestateManager();
    7184    ~GamestateManager();
    7285
    73     bool add(packet::Gamestate *gs, unsigned int clientID);
     86    virtual bool      addGamestate(packet::Gamestate *gs, unsigned int peerID);
     87    virtual bool      ackGamestate(unsigned int gamestateID, unsigned int peerID);
     88    virtual uint32_t  getLastProcessedGamestateID( unsigned int peerID );
     89    virtual uint32_t  getCurrentGamestateID(){ return currentGamestate_->getID(); }
     90   
    7491    bool processGamestates();
     92    bool sendAck(unsigned int gamestateID, uint32_t peerID);
    7593    bool update();
    76     void sendGamestates();
    77 //     packet::Gamestate *popGameState(unsigned int clientID);
    78     void finishGamestate( unsigned int clientID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate );
     94    std::vector<packet::Gamestate*> getGamestates();
     95    void finishGamestate( unsigned int peerID, packet::Gamestate*& destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate );
    7996
    8097    bool getSnapshot();
    8198
    82     bool ack(unsigned int gamestateID, unsigned int clientID);
    83     void removeClient(ClientInformation *client);
     99    void addPeer( uint32_t peerID );
     100    void setSynched( uint32_t peerID )
     101      { assert(peerMap_.find(peerID)!=peerMap_.end()); peerMap_[peerID].isSynched = true; }
     102    void removePeer( uint32_t peerID );
     103//     void removeClient(ClientInformation *client);
     104  protected:
     105    virtual bool sendPacket( packet::Packet* packet ) = 0;
    84106  private:
    85107    bool processGamestate(packet::Gamestate *gs);
    86108
    87     std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> > gamestateMap_;
     109//     std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> > gamestateMap_;
    88110    std::map<unsigned int, packet::Gamestate*> gamestateQueue;
    89     packet::Gamestate *reference;
    90     TrafficControl *trafficControl_;
     111//     std::map<unsigned int, uint32_t> lastProcessedGamestateID_;
     112    std::map<uint32_t, peerInfo> peerMap_;
     113    packet::Gamestate* currentGamestate_;
     114//     TrafficControl *trafficControl_;
    91115    unsigned int id_;
    92116//     boost::mutex* threadMutex_;
  • code/trunk/src/libraries/network/Host.cc

    r7284 r7801  
    4545  // Host*               Host::instance_=0;
    4646  uint32_t            Host::clientID_s=0;
    47   uint32_t            Host::shipID_s=-1;
     47//   uint32_t            Host::shipID_s=-1;
    4848  std::vector<Host*>  Host::instances_s;
    4949
     
    7676  * @return success?
    7777  */
    78   bool Host::addPacket(ENetPacket *packet, int clientID)
     78  void Host::addPacket(ENetPacket *packet, int clientID, uint8_t channelID)
    7979  {
    80     bool result = true;
    8180    for( std::vector<Host*>::iterator it = instances_s.begin(); it!=instances_s.end(); ++it )
    8281    {
    8382      if( (*it)->isActive() )
    8483      {
    85         if( !(*it)->queuePacket(packet, clientID) )
    86           result = false;
     84        (*it)->queuePacket(packet, clientID, channelID);
    8785      }
    8886    }
    89     return result;
    9087  }
    9188
  • code/trunk/src/libraries/network/Host.h

    r7284 r7801  
    3131
    3232#include "NetworkPrereqs.h"
     33#include "GamestateManager.h"
    3334#include "core/CorePrereqs.h"
    3435
     
    4950*       @author Oliver Scheuss
    5051*/
    51 class _NetworkExport Host{
     52class _NetworkExport Host: public GamestateManager
     53{
    5254  private:
    5355    //TODO add these functions or adequate
    5456    //virtual bool processChat(packet::Chat *message, unsigned int clientID)=0;
    5557    //virtual bool sendChat(packet::Chat *chat)=0;
    56     virtual bool queuePacket(ENetPacket *packet, int clientID)=0;
     58    virtual void queuePacket(ENetPacket *packet, int clientID, uint8_t channelID)=0;
    5759    virtual bool chat(const std::string& message)=0;
    5860    virtual bool broadcast(const std::string& message)=0;
     
    7173//     static Host* getInstance(){ return instance_; }
    7274    static bool running(){ return instances_s.size(); }
    73     static bool addPacket(ENetPacket *packet, int clientID=0);
     75    static void addPacket(ENetPacket* packet, int clientID = NETWORK_PEER_ID_SERVER, uint8_t channelID = 0);
    7476    //static bool chat(std::string& message);
    7577//     static bool receiveChat(packet::Chat *message, unsigned int clientID);
    7678    static unsigned int getPlayerID(){ return clientID_s; }
    77     static unsigned int getShipID(){return shipID_s;}
    7879    static void setClientID(unsigned int id){ clientID_s = id; }
    79     static void setShipID(unsigned int id){ shipID_s = id; }
    8080    static bool isServer();
    8181    static void Chat(const std::string& message);
     
    8686  private:
    8787    static uint32_t clientID_s;
    88     static uint32_t shipID_s;
    8988    static std::vector<Host*> instances_s;
    9089    bool bIsActive_;
  • code/trunk/src/libraries/network/LANDiscoverable.cc

    r7459 r7801  
    4545    this->host_ = 0;
    4646    this->bActive_ = false;
    47     this->setActivity(true);
     47//     this->setActivity(true);
    4848  }
    4949
  • code/trunk/src/libraries/network/MasterServer.cc

    r7786 r7801  
    280280     * any input/output bandwidth */
    281281    this->server = enet_host_create( &this->address, ORX_MSERVER_MAXCONNS,
    282         ORX_MSERVER_MAXCHANS, 0, 0 );     
     282        ORX_MSERVER_MAXCHANS, 0, 0 );
     283    assert(this->server);
    283284
    284285    /* see if creation worked */
  • code/trunk/src/libraries/network/MasterServer.h

    r7786 r7801  
    3030#define _MasterServer_H__
    3131
     32#include "NetworkPrereqs.h"
     33
    3234/* orxonox includes */
    3335#include <enet/enet.h>
     
    5052{
    5153  /* singleton */
    52   class MasterServer
     54  class _NetworkExport MasterServer
    5355  {
    5456    public:
  • code/trunk/src/libraries/network/MasterServerComm.cc

    r7786 r7801  
    4848
    4949    /* initialize the event holder */
    50     this->event = (ENetEvent *)calloc( sizeof(ENetEvent), 1 );
     50//     this->event = (ENetEvent *)calloc( sizeof(ENetEvent), 1 );
    5151   
    5252
     
    9090
    9191    /* Wait up to 2 seconds for the connection attempt to succeed. */
    92     if (enet_host_service (this->client, this->event, 2000) > 0 &&
    93         this->event->type == ENET_EVENT_TYPE_CONNECT )
     92    if (enet_host_service (this->client, &this->event, 500) > 0 &&
     93        this->event.type == ENET_EVENT_TYPE_CONNECT )
    9494      COUT(3) << "Connection to master server succeeded.\n";
    9595    else
     
    103103    return 0;
    104104  }
     105 
     106void MasterServerComm::update()
     107{
     108  while( enet_host_service( this->client, &this->event, 1 ) );
     109}
     110
    105111
    106112  int MasterServerComm::disconnect( void )
    107113  {
     114    while( enet_host_service( this->client, &this->event, 1 ) );
    108115    enet_peer_disconnect( this->peer, 0 );
    109116
     
    111118     * and drop any packets received packets.
    112119     */
    113     while (enet_host_service (this->client, this->event, 1000) > 0)
     120    while (enet_host_service (this->client, &this->event, 1000) > 0)
    114121    {
    115       switch (this->event->type)
     122      switch (this->event.type)
    116123      {
    117124        case ENET_EVENT_TYPE_RECEIVE:
    118           enet_packet_destroy (event->packet);
     125          enet_packet_destroy (event.packet);
    119126          break;
    120127
     
    154161    /* enet_host_service returns 0 if no event occured */
    155162    /* just newly set below test to >0 from >= 0, to be tested */
    156     if( enet_host_service( this->client, this->event, delayms ) > 0 )
     163    if( enet_host_service( this->client, &this->event, delayms ) > 0 )
    157164    {
    158165      /* check what type of event it is and react accordingly */
    159       switch (this->event->type)
     166      switch (this->event.type)
    160167      { /* new connection, not supposed to happen. */
    161168        case ENET_EVENT_TYPE_CONNECT: break;
     
    173180
    174181          /* resolve IP */
    175           enet_address_get_host_ip( &(this->event->peer->address),
     182          enet_address_get_host_ip( &(this->event.peer->address),
    176183            addrconv, 49 );
    177184
    178185          /* DEBUG */
    179186          COUT(3) << "MasterServer Debug: A packet of length "
    180             << this->event->packet->dataLength
    181             << " containing " << this->event->packet->data
     187            << this->event.packet->dataLength
     188            << " containing " << this->event.packet->data
    182189            << " was received from " << addrconv
    183             << " on channel " << this->event->channelID;
     190            << " on channel " << this->event.channelID;
    184191          /* END DEBUG */
    185192
    186193          /* call the supplied callback, if any. */
    187194          if( (*callback) != NULL )
    188             retval = (*callback)( addrconv, (this->event) );
     195            retval = (*callback)( addrconv, &(this->event) );
    189196
    190197          /* clean up */
    191           enet_packet_destroy( event->packet );
     198          enet_packet_destroy( event.packet );
    192199          if( addrconv )
    193200            free( addrconv );
     
    220227   
    221228    /* free the packet */
    222     enet_packet_destroy( packet );
     229    // PLEASE: never do this, because enet will free the packet once it's delivered. this will cause double frees
     230//     enet_packet_destroy( packet );
    223231
    224232    /* all done. */
     
    239247    /* One could just use enet_host_service() instead. */
    240248    enet_host_flush( this->client );
    241     enet_packet_destroy( packet );
     249    // PLEASE: never do this, because enet will free the packet once it's delivered. this will cause double frees
     250//     enet_packet_destroy( packet );
    242251
    243252    /* all done. */
  • code/trunk/src/libraries/network/MasterServerComm.h

    r7786 r7801  
    3030#define _MasterServerComm_H__
    3131
     32#include "NetworkPrereqs.h"
     33
    3234#include <cstdlib>
    3335#include <cstdio>
     
    3941namespace orxonox
    4042{
    41   class MasterServerComm
     43  class _NetworkExport MasterServerComm
    4244  {
    4345    public:
     
    5355       */
    5456      int initialize();
     57     
     58      void update();
    5559
    5660
     
    9296    private:
    9397      /** client handle */
    94       ENetHost *client;
     98      ENetHost* client;
    9599
    96100      /** event data holder */
    97       ENetEvent *event;
     101      ENetEvent event;
    98102
    99103      /** address holder */
     
    101105
    102106      /** peer data holder */
    103       ENetPeer *peer;
     107      ENetPeer* peer;
    104108  };
    105109
  • code/trunk/src/libraries/network/NetworkPrereqs.h

    r7490 r7801  
    6464namespace orxonox
    6565{
    66   static const unsigned int GAMESTATEID_INITIAL     = static_cast<unsigned int>(-1);
    67   static const unsigned int CLIENTID_UNKNOWN        = static_cast<unsigned int>(-2);
     66  static const unsigned int GAMESTATEID_INITIAL       = static_cast<unsigned int>(-1);
     67  static const unsigned int CLIENTID_UNKNOWN          = static_cast<unsigned int>(-2);
    6868  extern const char* LAN_DISCOVERY_MESSAGE;
    6969  extern const char* LAN_DISCOVERY_ACK;
    70   static const unsigned int LAN_DISCOVERY_PORT      = 55557;
     70  static const unsigned int LAN_DISCOVERY_PORT          = 55558;
     71  static const unsigned int NETWORK_PEER_ID_SERVER      = 0;
     72  static const unsigned int NETWORK_CHANNEL_DEFAULT     = 0;
     73  static const unsigned int NETWORK_CHANNEL_UNRELIABLE  = 1;
     74  static const unsigned int NETWORK_CHANNEL_COUNT       = 2;
    7175}
    7276
     
    8387      enum Value
    8488      {
    85         Reliable   = 1,
    86         Unsequence = 2,
    87         NoAllocate = 4
     89        Reliable    = 1,
     90        Unsequenced = 2,
     91        NoAllocate  = 4
    8892      };
    8993    }
     
    97101// from ENet
    98102struct _ENetPeer;
    99 typedef _ENetPeer ENetPeer;
     103typedef _ENetPeer     ENetPeer;
    100104struct _ENetPacket;
    101 typedef _ENetPacket ENetPacket;
     105typedef _ENetPacket   ENetPacket;
    102106struct _ENetEvent;
    103 typedef _ENetEvent ENetEvent;
     107typedef _ENetEvent    ENetEvent;
    104108struct _ENetHost;
    105 typedef _ENetHost ENetHost;
     109typedef _ENetHost     ENetHost;
    106110struct _ENetAddress;
    107 typedef _ENetAddress ENetAddress;
     111typedef _ENetAddress  ENetAddress;
     112typedef uint8_t       ENetChannelID;
    108113
    109114namespace orxonox
     
    161166}
    162167
     168namespace boost
     169{
     170  class mutex;
     171  class thread;
     172}
     173
    163174#endif /* _NetworkPrereqs_H__ */
  • code/trunk/src/libraries/network/Server.cc

    r7284 r7801  
    6060#include "FunctionCallManager.h"
    6161#include "GamestateManager.h"
     62#include "WANDiscovery.h"
    6263
    6364namespace orxonox
     
    99100  }
    100101
     102
     103  /** helper that connects to the master server */
     104  void Server::helper_ConnectToMasterserver()
     105  {
     106//     WANDiscovery::getInstance().msc.sendRequest( MSPROTO_GAME_SERVER " "
     107//       MSPROTO_REGISTER_SERVER );
     108  }
     109
    101110  /**
    102111  * This function opens the server by creating the listener thread
     
    107116    COUT(4) << "opening server" << endl;
    108117    this->openListener();
     118   
     119    /* make discoverable on LAN */
    109120    LANDiscoverable::setActivity(true);
     121
     122    /* make discoverable on WAN */
     123    WANDiscoverable::setActivity(true);
     124    /* TODO this needs to be optional, we need a switch from the UI to
     125     * enable/disable this
     126     */
     127//     helper_ConnectToMasterserver();
     128
     129    /* done */
    110130    return;
    111131  }
     
    120140    this->disconnectClients();
    121141    this->closeListener();
     142
     143    /* tell master server we're closing */
     144    COUT(2) << "disconnecting." << endl;
     145    WANDiscoverable::setActivity(false);   
     146    COUT(2) << "disconnecting done" << endl;
     147
    122148    LANDiscoverable::setActivity(false);
    123149    return;
     
    130156    while(temp){
    131157      chat = new packet::Chat(message, playerID);
    132       chat->setClientID(temp->getID());
    133       if(!chat->send())
     158      chat->setPeerID(temp->getID());
     159      if(!chat->send( static_cast<Host*>(this) ))
    134160        COUT(3) << "could not send Chat message to client ID: " << temp->getID() << std::endl;
    135161      temp = temp->next();
     
    139165  }
    140166
     167
     168  /* handle incoming data */
     169  int rephandler( char *addr, ENetEvent *ev )
     170  {
     171    /* reply to pings */
     172    if( !strncmp( (char *)ev->packet->data, MSPROTO_PING_GAMESERVER,
     173      MSPROTO_PING_GAMESERVER_LEN ) )
     174      //this->msc.sendRequest( MSPROTO_ACK );
     175      /* NOTE implement this after pollForReply
     176       * reimplementation
     177       */
     178      return 0;
     179
     180    /* done handling, return all ok code 0 */
     181    return 0;
     182  }
     183
     184  void Server::helper_HandleMasterServerRequests()
     185  {
     186    /* poll the master server for replies and see whether something
     187     * has to be done or changed.
     188     */
     189    //WANDiscovery::getInstance().msc.pollForReply( rhandler, 10 );
     190  }
    141191
    142192  /**
     
    149199    // receive incoming packets
    150200    Connection::processQueue();
     201
    151202    // receive and process incoming discovery packets
    152203    LANDiscoverable::update();
     204   
     205    // receive and process requests from master server
     206    /* todo */
     207    //helper_HandleMasterServerRequests();
    153208
    154209    if ( ClientInformation::hasClients() )
     
    156211      // process incoming gamestates
    157212      GamestateManager::processGamestates();
     213      FunctionCallManager::processBufferedFunctionCalls();
    158214
    159215      // send function calls to clients
    160       FunctionCallManager::sendCalls();
     216      FunctionCallManager::sendCalls( static_cast<Host*>(this) );
    161217
    162218      //this steers our network frequency
     
    167223        updateGamestate();
    168224      }
    169       sendPackets(); // flush the enet queue
    170     }
    171   }
    172 
    173   bool Server::queuePacket(ENetPacket *packet, int clientID)
    174   {
    175     return ServerConnection::addPacket(packet, clientID);
     225//       sendPackets(); // flush the enet queue
     226    }
     227  }
     228
     229  void Server::queuePacket(ENetPacket *packet, int clientID, uint8_t channelID)
     230  {
     231    ServerConnection::addPacket(packet, clientID, channelID);
    176232  }
    177233
     
    209265      return;
    210266    GamestateManager::update();
    211     COUT(5) << "Server: one gamestate update complete, goig to sendGameState" << std::endl;
     267//     COUT(5) << "Server: one gamestate update complete, goig to sendGameState" << std::endl;
    212268    //std::cout << "updated gamestate, sending it" << std::endl;
    213269    //if(clients->getGamestateID()!=GAMESTATEID_INITIAL)
    214     sendGameState();
     270    sendGameStates();
    215271    sendObjectDeletes();
    216     COUT(5) << "Server: one sendGameState turn complete, repeat in next tick" << std::endl;
     272//     COUT(5) << "Server: one sendGameState turn complete, repeat in next tick" << std::endl;
    217273    //std::cout << "sent gamestate" << std::endl;
    218274  }
    219275
    220   bool Server::processPacket( ENetPacket *packet, ENetPeer *peer ){
    221     packet::Packet *p = packet::Packet::createPacket(packet, peer);
    222     return p->process();
    223   }
    224 
    225   /**
    226   * sends the gamestate
    227   */
    228   bool Server::sendGameState()
    229   {
    230 //     COUT(5) << "Server: starting function sendGameState" << std::endl;
    231 //     ClientInformation *temp = ClientInformation::getBegin();
    232 //     bool added=false;
    233 //     while(temp != NULL){
    234 //       if( !(temp->getSynched()) ){
    235 //         COUT(5) << "Server: not sending gamestate" << std::endl;
    236 //         temp=temp->next();
    237 //         if(!temp)
    238 //           break;
    239 //         continue;
    240 //       }
    241 //       COUT(4) << "client id: " << temp->getID() << " RTT: " << temp->getRTT() << " loss: " << temp->getPacketLoss() << std::endl;
    242 //       COUT(5) << "Server: doing gamestate gamestate preparation" << std::endl;
    243 //       int cid = temp->getID(); //get client id
    244 //       packet::Gamestate *gs = GamestateManager::popGameState(cid);
    245 //       if(gs==NULL){
    246 //         COUT(2) << "Server: could not generate gamestate (NULL from compress)" << std::endl;
    247 //         temp = temp->next();
    248 //         continue;
    249 //       }
    250 //       //std::cout << "adding gamestate" << std::endl;
    251 //       gs->setClientID(cid);
    252 //       if ( !gs->send() ){
    253 //         COUT(3) << "Server: packet with client id (cid): " << cid << " not sended: " << temp->getFailures() << std::endl;
    254 //         temp->addFailure();
    255 //       }else
    256 //         temp->resetFailures();
    257 //       added=true;
    258 //       temp=temp->next();
    259 //       // gs gets automatically deleted by enet callback
    260 //     }
    261     GamestateManager::sendGamestates();
     276  /**
     277  * sends the current gamestate to all peers
     278  */
     279  bool Server::sendGameStates()
     280  {
     281    std::vector<packet::Gamestate*> gamestates = GamestateManager::getGamestates();
     282    std::vector<packet::Gamestate*>::iterator it;
     283    for( it = gamestates.begin(); it != gamestates.end(); ++it )
     284    {
     285      (*it)->send(static_cast<Host*>(this));
     286    }
    262287    return true;
    263288  }
     289
    264290
    265291  bool Server::sendObjectDeletes()
     
    286312      packet::DeleteObjects *cd = new packet::DeleteObjects(*del);
    287313      assert(cd);
    288       cd->setClientID(cid);
    289       if ( !cd->send() )
    290         COUT(3) << "Server: packet with client id (cid): " << cid << " not sended: " << temp->getFailures() << std::endl;
     314      cd->setPeerID(cid);
     315      if ( !cd->send( static_cast<Host*>(this) ) )
     316        COUT(3) << "Server: packet with client id (cid): " << cid << " not sended" << std::endl;
    291317      temp=temp->next();
    292318      // gs gets automatically deleted by enet callback
     
    312338    // inform all the listeners
    313339    ClientConnectionListener::broadcastClientConnected(newid);
     340    GamestateManager::addPeer(newid);
    314341
    315342    ++newid;
     
    327354    else
    328355    {
     356      GamestateManager::removePeer(client->getID());
    329357      //ServerConnection::disconnectClient( client );
    330358      //ClientConnectionListener::broadcastClientDisconnected( client->getID() ); //this is done in ClientInformation now
     
    332360    }
    333361  }
     362 
     363  void Server::processPacket(packet::Packet* packet)
     364  {
     365    if( packet->isReliable() )
     366    {
     367      if( this->getLastProcessedGamestateID(packet->getPeerID()) >= packet->getRequiredGamestateID() )
     368        packet->process(static_cast<Host*>(this));
     369      else
     370        this->packetQueue_.push_back(packet);
     371    }
     372    else
     373      packet->process(static_cast<Host*>(this));
     374  }
     375
    334376
    335377  bool Server::createClient(int clientID)
     
    341383      return false;
    342384    }
    343     COUT(5) << "Con.Man: creating client id: " << temp->getID() << std::endl;
     385    COUT(4) << "Con.Man: creating client id: " << temp->getID() << std::endl;
    344386
    345387    // synchronise class ids
     
    348390    // now synchronise functionIDs
    349391    packet::FunctionIDs *fIDs = new packet::FunctionIDs();
    350     fIDs->setClientID(clientID);
    351     bool b = fIDs->send();
     392    fIDs->setPeerID(clientID);
     393    bool b = fIDs->send( static_cast<Host*>(this) );
    352394    assert(b);
    353395
    354396    temp->setSynched(true);
     397    GamestateManager::setSynched(clientID);
     398   
    355399    COUT(4) << "sending welcome" << std::endl;
    356400    packet::Welcome *w = new packet::Welcome(temp->getID(), temp->getShipID());
    357     w->setClientID(temp->getID());
    358     b = w->send();
     401    w->setPeerID(temp->getID());
     402    b = w->send( static_cast<Host*>(this) );
    359403    assert(b);
    360404    packet::Gamestate *g = new packet::Gamestate();
    361     g->setClientID(temp->getID());
    362     b = g->collectData(0,0x1);
     405    g->setPeerID(temp->getID());
     406    b = g->collectData(0,packet::GAMESTATE_MODE_SERVER);
     407    assert(b);
    363408    if(!b)
    364409      return false; //no data for the client
    365     b = g->compressData();
    366     assert(b);
    367     b = g->send();
     410//     b = g->compressData();
     411//     assert(b);
     412    b = g->send( static_cast<Host*>(this) );
    368413    assert(b);
    369414    return true;
     
    373418  {
    374419    ServerConnection::disconnectClient( client );
    375     GamestateManager::removeClient(client);
     420    GamestateManager::removePeer(client->getID());
    376421    // inform all the listeners
    377422    // ClientConnectionListener::broadcastClientDisconnected(client->getID()); // this is done in ClientInformation now
     
    395440    {
    396441      chat = new packet::Chat(message, clientID);
    397       chat->setClientID(temp->getID());
    398       if(!chat->send())
     442      chat->setPeerID(temp->getID());
     443      if(!chat->send( static_cast<Host*>(this) ))
    399444        COUT(3) << "could not send Chat message to client ID: " << temp->getID() << std::endl;
    400445      temp = temp->next();
     
    411456    int failures=0;
    412457    packet::ClassID *classid = new packet::ClassID();
    413     classid->setClientID(clientID);
    414     while(!classid->send() && failures < 10){
     458    classid->setPeerID(clientID);
     459    while(!classid->send( static_cast<Host*>(this) ) && failures < 10){
    415460      failures++;
    416461    }
  • code/trunk/src/libraries/network/Server.h

    r7163 r7801  
    3232#include "NetworkPrereqs.h"
    3333
     34#include <deque>
     35
    3436#include "util/UtilPrereqs.h"
    3537#include "core/CorePrereqs.h"
    3638#include "Host.h"
    37 #include "GamestateManager.h"
     39// #include "GamestateManager.h"
    3840#include "ServerConnection.h"
    3941#include "LANDiscoverable.h"
     42#include "WANDiscoverable.h"
     43// #include "MasterServerComm.h"
     44// #include "MasterServerProtocol.h"
     45
    4046
    4147namespace orxonox
     
    4652  * It implements all functions necessary for a Server
    4753  */
    48   class _NetworkExport Server : public Host, public ServerConnection, public GamestateManager, public LANDiscoverable{
     54  class _NetworkExport Server : public Host, public ServerConnection, public LANDiscoverable, public WANDiscoverable
     55  {
    4956  public:
    5057    Server();
     
    5360    ~Server();
    5461
     62    /* helpers */
     63    void helper_ConnectToMasterserver();
     64    void helper_HandleMasterServerRequests();
     65    int replyhandler( char *addr, ENetEvent *ev );
     66
    5567    void open();
    5668    void close();
    5769    bool processChat(const std::string& message, unsigned int playerID);
    58     bool queuePacket(ENetPacket *packet, int clientID);
     70    void queuePacket(ENetPacket *packet, int clientID, uint8_t channelID);
     71    virtual bool sendPacket( packet::Packet* packet ){ return packet->send( static_cast<Host*>(this) ); }
    5972    void update(const Clock& time);
    6073    unsigned int getRTT(unsigned int clientID);
     
    6578  private:
    6679    virtual bool isServer_(){return true;}
    67     unsigned int shipID(){return 0;}
    6880    unsigned int playerID(){return 0;}
    6981
    7082    void addPeer(ENetEvent *event);
    7183    void removePeer(ENetEvent *event);
     84    void processPacket(packet::Packet* packet);
    7285
    7386    bool createClient(int clientID);
    7487    void disconnectClient( ClientInformation *client);
    75     bool processPacket( ENetPacket *packet, ENetPeer *peer );
    76     bool sendGameState();
     88    bool sendGameStates();
    7789    bool sendObjectDeletes();
    7890    virtual bool chat(const std::string& message);
     
    8294
    8395    float timeSinceLastUpdate_;
     96    std::deque<packet::Packet*> packetQueue_;
    8497  };
    8598
  • code/trunk/src/libraries/network/ServerConnection.cc

    r7459 r7801  
    4949  }
    5050
    51   ServerConnection::~ServerConnection(){
     51  ServerConnection::~ServerConnection()
     52  {
    5253    if ( this->bListening_ )
    5354      closeListener();
     
    5556  }
    5657
    57   void ServerConnection::setBindAddress( const std::string& bindAddress ) {
     58  void ServerConnection::setBindAddress( const std::string& bindAddress )
     59  {
    5860    if (enet_address_set_host (this->bindAddress_, bindAddress.c_str()) < 0)
    5961        COUT(1) << "Error: Could not resolve \"" << bindAddress << "\"." << std::endl;
     
    6466  }
    6567
    66   bool ServerConnection::openListener() {
    67     this->host_ = enet_host_create(this->bindAddress_, NETWORK_MAX_CONNECTIONS, 0, 0, 0);
     68  bool ServerConnection::openListener()
     69  {
     70    // create host
     71    this->host_ = enet_host_create(this->bindAddress_, NETWORK_MAX_CONNECTIONS, NETWORK_CHANNEL_COUNT, 0, 0);
     72   
    6873    if ( this->host_ == NULL )
    6974    {
     
    7176        return false;
    7277    }
     78   
     79    // enable compression
     80    this->enableCompression();
    7381    assert( this->host_->socket4 != ENET_SOCKET_NULL || this->host_->socket6 != ENET_SOCKET_NULL );
    7482    if (this->host_->socket4 == ENET_SOCKET_NULL)
     
    7886    else
    7987        COUT(3) << "Info: Using IPv4 and IPv6 Sockets." << std::endl;
     88   
     89    // start communication thread
     90    Connection::startCommunicationThread();
    8091
    8192    return true;
    8293  }
    8394
    84   bool ServerConnection::closeListener() {
     95  bool ServerConnection::closeListener()
     96  {
    8597    this->bListening_=false;
    8698    disconnectClients();
     99    Connection::stopCommunicationThread();
    87100    enet_host_destroy(this->host_);
    88101    return true;
    89102  }
    90103
    91   bool ServerConnection::addPacket(ENetPacket *packet, unsigned int clientID) {
     104  void ServerConnection::addPacket(ENetPacket *packet, unsigned int clientID, uint8_t channelID)
     105  {
    92106    if ( clientID == CLIENTID_UNKNOWN )
    93107    {
    94       return addPacketAll(packet);
     108      broadcastPacket(packet, channelID);
    95109    }
    96110    else
     
    99113      if(!temp){
    100114        COUT(3) << "C.Man: addPacket findClient failed" << std::endl;
    101         return false;
    102115      }
    103       return Connection::addPacket(packet, temp->getPeer());
     116      Connection::addPacket(packet, temp->getPeer(), channelID);
    104117    }
    105   }
    106 
    107   bool ServerConnection::addPacketAll(ENetPacket *packet) {
    108 //     if ( !Connection::getInstance() )
    109 //       return false;
    110     enet_host_broadcast( Connection::getHost(), 0, packet);
    111     return true;
    112118  }
    113119
     
    117123  }
    118124
    119   void ServerConnection::disconnectClient(int clientID){
     125  void ServerConnection::disconnectClient(int clientID)
     126  {
    120127    ClientInformation *client = ClientInformation::findClient(clientID);
    121128    if(client)
     
    123130  }
    124131
    125   void ServerConnection::disconnectClients() {
    126     ENetEvent event;
     132  void ServerConnection::disconnectClients()
     133  {
    127134    ClientInformation *temp = ClientInformation::getBegin();
    128     while(temp!=0){
     135    while(temp!=0)
     136    {
    129137      ServerConnection::disconnectClient( temp );
    130138      temp = temp->next();
    131     }
    132     temp = ClientInformation::getBegin();
    133     while( temp!=0 ){
    134       if( service( &event ) )
    135       {
    136         switch (event.type)
    137         {
    138         case ENET_EVENT_TYPE_NONE: break;
    139         case ENET_EVENT_TYPE_CONNECT: break;
    140         case ENET_EVENT_TYPE_RECEIVE:
    141           enet_packet_destroy(event.packet);
    142           break;
    143         case ENET_EVENT_TYPE_DISCONNECT:
    144           removePeer( &event );
    145           temp = ClientInformation::getBegin();
    146           break;
    147         }
    148       }
    149139    }
    150140    return;
     
    152142
    153143
    154   int ServerConnection::getClientID(ENetPeer* peer) {
     144  int ServerConnection::getClientID(ENetPeer* peer)
     145  {
    155146    return getClientID(&(peer->address));
    156147  }
    157148
    158   int ServerConnection::getClientID(ENetAddress* address) {
     149  int ServerConnection::getClientID(ENetAddress* address)
     150  {
    159151    return ClientInformation::findClient(address)->getID();
    160152  }
    161153
    162   ENetPeer *ServerConnection::getClientPeer(int clientID) {
     154  ENetPeer *ServerConnection::getClientPeer(int clientID)
     155  {
    163156    return ClientInformation::findClient(clientID)->getPeer();
    164157  }
  • code/trunk/src/libraries/network/ServerConnection.h

    r7163 r7801  
    5656    bool openListener();
    5757    bool closeListener();
    58     bool addPacket(ENetPacket *packet, unsigned int ID);
    59     bool addPacketAll(ENetPacket *packet);
     58    void addPacket(ENetPacket *packet, unsigned int ID, uint8_t channelID);
    6059    virtual void disconnectClient(ClientInformation *client);
    6160    void disconnectClient(int clientID);
  • code/trunk/src/libraries/network/WANDiscovery.cc

    r7786 r7801  
    3939namespace orxonox
    4040{
    41   ManageScopedSingleton(WANDiscovery, ScopeID::Root, true);
     41  ManageScopedSingleton(WANDiscovery, ScopeID::Graphics, true);
    4242
    4343
     
    7171     * has changed.
    7272     */
    73     SetConfigValue( msaddress, "localhost");
     73    SetConfigValue( msaddress, "orxonox.net");
    7474  }
    7575
  • code/trunk/src/libraries/network/packet/Acknowledgement.cc

    r6417 r7801  
    3131#include "util/Debug.h"
    3232#include "network/GamestateHandler.h"
     33#include "network/Host.h"
    3334
    3435namespace orxonox {
     
    3940#define _ACKID              _PACKETID + sizeof(packet::Type::Value)
    4041
    41 Acknowledgement::Acknowledgement( unsigned int id, unsigned int clientID )
     42Acknowledgement::Acknowledgement( unsigned int id, unsigned int peerID )
    4243 : Packet()
    4344{
     
    4647  *(Type::Value *)(data_ + _PACKETID ) = Type::Acknowledgement;
    4748  *(uint32_t *)(data_ + _ACKID ) = id;
    48   clientID_=clientID;
     49  peerID_=peerID;
    4950}
    5051
    51 Acknowledgement::Acknowledgement( uint8_t *data, unsigned int clientID )
    52   : Packet(data, clientID)
     52Acknowledgement::Acknowledgement( uint8_t *data, unsigned int peerID )
     53  : Packet(data, peerID)
    5354{
    5455}
     
    6263}
    6364
    64 bool Acknowledgement::process(){
     65bool Acknowledgement::process(orxonox::Host* host){
    6566  COUT(5) << "processing ACK with ID: " << getAckID() << endl;
    66   bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
     67  bool b = host->ackGamestate(getAckID(), peerID_);
    6768  delete this;
    6869  return b;
  • code/trunk/src/libraries/network/packet/Acknowledgement.h

    r6073 r7801  
    4242{
    4343public:
    44   Acknowledgement( unsigned int id, unsigned int clientID );
    45   Acknowledgement( uint8_t* data, unsigned int clientID );
     44  Acknowledgement( unsigned int id, unsigned int peerID );
     45  Acknowledgement( uint8_t* data, unsigned int peerID );
    4646  ~Acknowledgement();
    4747
    4848  inline unsigned int getSize() const;
    49   bool process();
     49  virtual bool process(orxonox::Host* host);
    5050
    5151  unsigned int getAckID();
  • code/trunk/src/libraries/network/packet/Chat.cc

    r7163 r7801  
    8080}
    8181
    82 bool Chat::process(){
    83   bool b = Host::incomingChat(std::string((const char*)data_+_MESSAGE), *(uint32_t *)(data_+_PLAYERID));
     82bool Chat::process(orxonox::Host* host){
     83  bool b = host->incomingChat(std::string((const char*)data_+_MESSAGE), *(uint32_t *)(data_+_PLAYERID));
    8484  delete this;
    8585  return b;
  • code/trunk/src/libraries/network/packet/Chat.h

    r7163 r7801  
    5252
    5353  /* process chat message packet and remove it afterwards */
    54   bool process();
     54  virtual bool process(orxonox::Host* host);
    5555
    5656  /* Get the length of the message (not the full size of the packet) */
  • code/trunk/src/libraries/network/packet/ClassID.cc

    r7163 r7801  
    120120
    121121
    122 bool ClassID::process(){
     122bool ClassID::process(orxonox::Host* host){
    123123  int nrOfClasses;
    124124  uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
  • code/trunk/src/libraries/network/packet/ClassID.h

    r6417 r7801  
    4848
    4949  uint32_t getSize() const;
    50   bool process();
     50  virtual bool process(orxonox::Host* host);
    5151
    5252private:
  • code/trunk/src/libraries/network/packet/DeleteObjects.cc

    r6417 r7801  
    5757}
    5858
    59 bool DeleteObjects::fetchIDs(){
     59bool DeleteObjects::fetchIDs()
     60{
    6061  unsigned int number = Synchronisable::getNumberOfDeletedObject();
    6162  if(number==0)
     
    7980}
    8081
    81 unsigned int DeleteObjects::getSize() const{
     82unsigned int DeleteObjects::getSize() const
     83{
    8284  assert(data_);
    8385  return _OBJECTIDS + *(uint32_t*)(data_+_QUANTITY)*sizeof(uint32_t);
    8486}
    8587
    86 bool DeleteObjects::process(){
    87   for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++){
     88bool DeleteObjects::process(orxonox::Host* host)
     89{
     90  for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++)
     91  {
    8892    COUT(4) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;
    8993    Synchronisable::deleteObject( *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) );
  • code/trunk/src/libraries/network/packet/DeleteObjects.h

    r6073 r7801  
    3232#include "Packet.h"
    3333
    34 namespace orxonox {
    35 namespace packet {
     34namespace orxonox
     35{
     36namespace packet
     37{
    3638/**
    3739    @author
     
    4749
    4850  inline unsigned int getSize() const;
    49   bool process();
     51  virtual bool process(orxonox::Host* host);
    5052
    5153private:
  • code/trunk/src/libraries/network/packet/FunctionCalls.cc

    r7495 r7801  
    3232#include "network/FunctionCall.h"
    3333#include "network/FunctionCallManager.h"
     34#include "network/GamestateHandler.h"
    3435
    3536namespace orxonox {
     
    4041const unsigned int FUNCTIONCALLS_MEM_ALLOCATION = 1000;
    4142
    42 FunctionCalls::FunctionCalls()
    43  : Packet()
     43FunctionCalls::FunctionCalls():
     44  Packet(), minGamestateID_(GAMESTATEID_INITIAL)
    4445{
    4546  flags_ = flags_ | PACKET_FLAGS_FUNCTIONCALLS;
    46   currentSize_ = 2*sizeof(uint32_t); // for packetid and nrOfCalls
     47  currentSize_ = 3*sizeof(uint32_t); // for packetid, nrOfCalls and minGamestateID_
    4748}
    4849
    49 FunctionCalls::FunctionCalls( uint8_t* data, unsigned int clientID )
    50   : Packet(data, clientID)
     50FunctionCalls::FunctionCalls( uint8_t* data, unsigned int clientID ):
     51  Packet(data, clientID), minGamestateID_(GAMESTATEID_INITIAL)
    5152{
    5253}
     
    5758
    5859
    59 bool FunctionCalls::process(){
     60bool FunctionCalls::process(orxonox::Host* host)
     61{
    6062  assert(isDataENetAllocated());
    6163 
    6264  uint8_t* temp = data_+sizeof(uint32_t); //skip packetid
    6365  uint32_t nrOfCalls = *(uint32_t*)temp;
     66  temp += sizeof(uint32_t);
     67  this->minGamestateID_ = *(uint32_t*)temp;
    6468  temp += sizeof(uint32_t);
    6569  for( unsigned int i = 0; i<nrOfCalls; i++ )
     
    6872    fctCall.loadData(temp);
    6973    if( !fctCall.execute() )
    70       FunctionCallManager::bufferIncomingFunctionCall( fctCall );
     74    {
     75      FunctionCallManager::bufferIncomingFunctionCall( fctCall, minGamestateID_, this->getPeerID() );
     76    }
    7177  }
    7278 
     
    7581}
    7682
    77 void FunctionCalls::addCallStatic( uint32_t networkID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
     83void FunctionCalls::addCallStatic( uint32_t networkID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5)
     84{
    7885  assert(!isDataENetAllocated());
    7986 
     
    8390}
    8491
    85 void FunctionCalls::addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
     92void FunctionCalls::addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5)
     93{
    8694  assert(!isDataENetAllocated());
    8795 
     
    9199}
    92100
    93 bool FunctionCalls::send()
     101bool FunctionCalls::send(orxonox::Host* host)
    94102{
     103  this->minGamestateID_ = host->getCurrentGamestateID();
    95104  assert(this->functionCalls_.size());
    96105  data_=new uint8_t[ currentSize_ ];
    97106  *(Type::Value *)(data_ + _PACKETID ) = Type::FunctionCalls; // Set the Packet ID
    98   *(uint32_t*)(data_+sizeof(uint32_t)) = this->functionCalls_.size(); // set nrOfCalls to 0
    99   uint8_t* temp = data_+2*sizeof(uint32_t);
     107  *(uint32_t*)(data_+sizeof(uint32_t)) = this->functionCalls_.size(); // set nrOfCalls
     108  *(uint32_t*)(data_+2*sizeof(uint32_t)) = this->minGamestateID_; // set minGamestateID_
     109  uint8_t* temp = data_+3*sizeof(uint32_t);
    100110 
    101111  while( this->functionCalls_.size() )
     
    107117  assert( temp==data_+currentSize_ );
    108118 
    109   Packet::send();
     119  Packet::send(host);
    110120  return true;
    111121}
  • code/trunk/src/libraries/network/packet/FunctionCalls.h

    r7490 r7801  
    5454  inline unsigned int getSize() const
    5555    { assert(!this->isDataENetAllocated()); return currentSize_; }
    56   bool process();
     56  virtual bool process(orxonox::Host* host);
    5757
    5858  void addCallStatic( uint32_t networkID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
    5959  void addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
    60   virtual bool send();
     60  virtual bool send(orxonox::Host* host);
    6161private:
    6262  std::queue<orxonox::FunctionCall> functionCalls_;
    6363  unsigned int                      clientID_;
     64  uint32_t                          minGamestateID_;
    6465  uint32_t                          currentSize_;
    6566};
  • code/trunk/src/libraries/network/packet/FunctionIDs.cc

    r6417 r7801  
    4646
    4747
    48 FunctionIDs::FunctionIDs( ) : Packet(){
     48FunctionIDs::FunctionIDs( ) : Packet()
     49{
    4950  unsigned int nrOfFunctions=0;
    5051  unsigned int packetSize=2*sizeof(uint32_t); //space for the packetID and for the nroffunctions
     
    5556  //calculate total needed size (for all strings and integers)
    5657  ObjectList<NetworkFunctionBase>::iterator it;
    57   for(it = ObjectList<NetworkFunctionBase>::begin(); it; ++it){
     58  for(it = ObjectList<NetworkFunctionBase>::begin(); it; ++it)
     59  {
    5860    const std::string& functionname = it->getName();
    5961    networkID = it->getNetworkID();
     
    7678  // now save all classids and classnames
    7779  std::pair<uint32_t, std::string> tempPair;
    78   while( !tempQueue.empty() ){
     80  while( !tempQueue.empty() )
     81  {
    7982    tempPair = tempQueue.front();
    8083    tempQueue.pop();
     
    98101}
    99102
    100 uint32_t FunctionIDs::getSize() const{
     103uint32_t FunctionIDs::getSize() const
     104{
    101105  assert(this->data_);
    102106  uint8_t *temp = data_+sizeof(uint32_t); // packet identification
     
    114118
    115119
    116 bool FunctionIDs::process(){
     120bool FunctionIDs::process(orxonox::Host* host)
     121{
    117122  int nrOfFunctions;
    118123  uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
     
    127132  temp += sizeof(uint32_t);
    128133
    129   for( int i=0; i<nrOfFunctions; i++){
     134  for( int i=0; i<nrOfFunctions; i++)
     135  {
    130136    networkID = *(uint32_t*)temp;
    131137    stringsize = *(uint32_t*)(temp+sizeof(uint32_t));
  • code/trunk/src/libraries/network/packet/FunctionIDs.h

    r6417 r7801  
    4747  ~FunctionIDs();
    4848
    49   uint32_t getSize() const;
    50   bool process();
     49  virtual uint32_t getSize() const;
     50  virtual bool process(orxonox::Host* host);
    5151
    5252private:
  • code/trunk/src/libraries/network/packet/Gamestate.cc

    r7163 r7801  
    3636#include "network/synchronisable/Synchronisable.h"
    3737#include "network/GamestateHandler.h"
     38#include "network/Host.h"
    3839
    3940namespace orxonox {
     
    4344#define GAMESTATE_START(data) (data + GamestateHeader::getSize())
    4445
    45 #define PACKET_FLAG_GAMESTATE  PacketFlag::Reliable
     46// #define PACKET_FLAG_GAMESTATE  PacketFlag::Reliable
     47#define PACKET_FLAG_GAMESTATE  0
    4648
    4749inline bool memzero( uint8_t* data, uint32_t datalength)
     
    6567
    6668Gamestate::Gamestate():
    67   header_(0)
     69  header_()
    6870{
    6971  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     
    7274
    7375Gamestate::Gamestate(uint8_t *data, unsigned int clientID):
    74   Packet(data, clientID)
     76  Packet(data, clientID), header_(data)
    7577{
    7678  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
    77   header_ = new GamestateHeader(data_);
    78 }
    79 
    80 
    81 Gamestate::Gamestate(uint8_t *data)
     79}
     80
     81
     82Gamestate::Gamestate(uint8_t *data):
     83  header_(data)
    8284{
    8385  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
    8486  data_ = data;
    85   header_ = new GamestateHeader(data_);
    8687}
    8788
    8889
    8990Gamestate::Gamestate(const Gamestate& g) :
    90     Packet( *(Packet*)&g ), nrOfVariables_(0)
     91  Packet( *(Packet*)&g ), header_(this->data_), nrOfVariables_(0)
    9192{
    9293  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
    93   header_ = new GamestateHeader(data_);
    9494  sizes_ = g.sizes_;
    9595}
     
    9898Gamestate::~Gamestate()
    9999{
    100   if( header_ )
    101     delete header_;
    102100}
    103101
     
    105103bool Gamestate::collectData(int id, uint8_t mode)
    106104{
    107   assert(this->header_==0); // make sure the header didn't exist before
    108105  uint32_t tempsize=0, currentsize=0;
    109106  assert(data_==0);
     
    120117  }
    121118
    122   // create the header object
    123   assert( header_ == 0 );
    124   header_ = new GamestateHeader(data_);
     119  // tell the gamestate header where to store the data
     120  header_.setData(this->data_);
    125121
    126122  //start collect data synchronisable by synchronisable
     
    142138      assert(0); // if we don't use multithreading this part shouldn't be neccessary
    143139      // start allocate additional memory
    144       COUT(3) << "G.St.Man: need additional memory" << std::endl;
     140      COUT(3) << "Gamestate: need additional memory" << std::endl;
    145141      ObjectList<Synchronisable>::iterator temp = it;
    146142      uint32_t addsize=tempsize;
     
    161157
    162158  //start write gamestate header
    163   header_->setDataSize( currentsize );
    164   header_->setID( id );
    165   header_->setBaseID( GAMESTATEID_INITIAL );
    166   header_->setDiffed( false );
    167   header_->setComplete( true );
    168   header_->setCompressed( false );
     159  header_.setDataSize( currentsize );
     160  header_.setID( id );
     161  header_.setBaseID( GAMESTATEID_INITIAL );
     162  header_.setDiffed( false );
     163  header_.setComplete( true );
     164  header_.setCompressed( false );
    169165  //stop write gamestate header
    170166
    171   COUT(5) << "G.ST.Man: Gamestate size: " << currentsize << std::endl;
    172   COUT(5) << "G.ST.Man: 'estimated' (and corrected) Gamestate size: " << size << std::endl;
     167  COUT(5) << "Gamestate: Gamestate size: " << currentsize << std::endl;
     168  COUT(5) << "Gamestate: 'estimated' (and corrected) Gamestate size: " << size << std::endl;
    173169  return true;
    174170}
     
    177173bool Gamestate::spreadData(uint8_t mode)
    178174{
    179   COUT(4) << "processing gamestate with id " << header_->getID() << endl;
     175  COUT(5) << "processing gamestate with id " << header_.getID() << endl;
    180176  assert(data_);
    181   assert(!header_->isCompressed());
     177  assert(!header_.isCompressed());
    182178  uint8_t *mem=data_+GamestateHeader::getSize();
    183179  Synchronisable *s;
    184 
     180 
    185181  // update the data of the objects we received
    186   while(mem < data_+GamestateHeader::getSize()+header_->getDataSize())
     182  while(mem < data_+GamestateHeader::getSize()+header_.getDataSize())
    187183  {
    188184    SynchronisableHeader objectheader(mem);
     
    197193      else
    198194      {
     195//         COUT(4) << "not creating object of classid " << objectheader.getClassID() << endl;
    199196        mem += objectheader.getDataSize() + ( objectheader.isDiffed() ? SynchronisableHeaderLight::getSize() : SynchronisableHeader::getSize() );
    200197      }
     
    202199    else
    203200    {
     201//       COUT(4) << "updating object of classid " << objectheader.getClassID() << endl;
    204202      bool b = s->updateData(mem, mode);
    205203      assert(b);
    206204    }
    207205  }
     206  assert(mem-data_ == GamestateHeader::getSize()+header_.getDataSize());
     207 
    208208   // In debug mode, check first, whether there are no duplicate objectIDs
    209209#ifndef NDEBUG
     
    249249{
    250250  assert(data_);
    251   if(header_->isCompressed())
    252     return header_->getCompSize()+GamestateHeader::getSize();
     251  if(header_.isCompressed())
     252    return header_.getCompSize()+GamestateHeader::getSize();
    253253  else
    254254  {
    255     return header_->getDataSize()+GamestateHeader::getSize();
     255    return header_.getDataSize()+GamestateHeader::getSize();
    256256  }
    257257}
     
    271271
    272272
    273 bool Gamestate::process()
    274 {
    275   return GamestateHandler::addGamestate(this, getClientID());
     273bool Gamestate::process(orxonox::Host* host)
     274{
     275  return host->addGamestate(this, getPeerID());
    276276}
    277277
     
    280280{
    281281  assert(data_);
    282   assert(!header_->isCompressed());
    283   uLongf buffer = (uLongf)(((header_->getDataSize() + 12)*1.01)+1);
     282  assert(!header_.isCompressed());
     283  uLongf buffer = (uLongf)(((header_.getDataSize() + 12)*1.01)+1);
    284284  if(buffer==0)
    285285    return false;
     
    289289  uint8_t *source = data_ + GamestateHeader::getSize();
    290290  int retval;
    291   retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) );
     291  retval = compress( dest, &buffer, source, (uLong)(header_.getDataSize()) );
    292292  switch ( retval )
    293293  {
     
    299299
    300300  //copy and modify header
    301   GamestateHeader *temp = header_;
    302   header_ = new GamestateHeader(ndata, temp);
     301  GamestateHeader *temp = new GamestateHeader(data_);
     302  header_.setData(ndata);
     303  header_ = *temp;
    303304  delete temp;
    304305  //delete old data
     
    306307  //save new data
    307308  data_ = ndata;
    308   header_->setCompSize( buffer );
    309   header_->setCompressed( true );
    310   COUT(0) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;
     309  header_.setCompSize( buffer );
     310  header_.setCompressed( true );
     311  COUT(4) << "gamestate compress datasize: " << header_.getDataSize() << " compsize: " << header_.getCompSize() << std::endl;
    311312  return true;
    312313}
     
    316317{
    317318  assert(data_);
    318   assert(header_->isCompressed());
    319   COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_->getID() << ", baseid: " << header_->getBaseID() << ", datasize: " << header_->getDataSize() << ", compsize: " << header_->getCompSize() << std::endl;
    320   uint32_t datasize = header_->getDataSize();
    321   uint32_t compsize = header_->getCompSize();
     319  assert(header_.isCompressed());
     320  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_.getID() << ", baseid: " << header_.getBaseID() << ", datasize: " << header_.getDataSize() << ", compsize: " << header_.getCompSize() << std::endl;
     321  uint32_t datasize = header_.getDataSize();
     322  uint32_t compsize = header_.getCompSize();
    322323  uint32_t bufsize;
    323324  bufsize = datasize;
     
    338339
    339340  //copy over the header
    340   GamestateHeader *temp = header_;
    341   header_ = new GamestateHeader( data_, header_ );
     341  GamestateHeader* temp = new GamestateHeader( data_ );
     342  header_.setData(ndata);
     343  header_ = *temp;
    342344  delete temp;
    343345
     
    357359  //set new pointers
    358360  data_ = ndata;
    359   header_->setCompressed( false );
    360   assert(header_->getDataSize()==datasize);
    361   assert(header_->getCompSize()==compsize);
     361  header_.setCompressed( false );
     362  assert(header_.getDataSize()==datasize);
     363  assert(header_.getCompSize()==compsize);
    362364  return true;
    363365}
    364366
    365367
     368inline void /*Gamestate::*/diffObject( uint8_t*& newDataPtr, uint8_t*& origDataPtr, uint8_t*& baseDataPtr, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes )
     369{
     370  assert( objectHeader.getDataSize() == SynchronisableHeader(baseDataPtr).getDataSize() );
     371 
     372  uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData
     373  // Check whether the whole object stayed the same
     374  if( memcmp( origDataPtr+objectOffset, baseDataPtr+objectOffset, objectHeader.getDataSize()) == 0 )
     375  {
     376//     COUT(4) << "skip object " << Synchronisable::getSynchronisable(objectHeader.getObjectID())->getIdentifier()->getName() << endl;
     377    origDataPtr += objectOffset + objectHeader.getDataSize(); // skip the whole object
     378    baseDataPtr += objectOffset + objectHeader.getDataSize();
     379    sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables();
     380  }
     381  else
     382  {
     383    // Now start to diff the Object
     384    SynchronisableHeaderLight newObjectHeader(newDataPtr);
     385    newObjectHeader = objectHeader; // copy over the objectheader
     386    VariableID variableID = 0;
     387    uint32_t diffedObjectOffset = SynchronisableHeaderLight::getSize();
     388    // iterate through all variables
     389    while( objectOffset < objectHeader.getDataSize()+SynchronisableHeader::getSize() )
     390    {
     391      // check whether variable changed and write id and copy over variable to the new stream
     392      // otherwise skip variable
     393      uint32_t varSize = *sizes;
     394      assert( varSize == Synchronisable::getSynchronisable(objectHeader.getObjectID())->getVarSize(variableID) );
     395      if ( varSize != 0 )
     396      {
     397        if ( memcmp(origDataPtr+objectOffset, baseDataPtr+objectOffset, varSize) != 0 )
     398        {
     399          *(VariableID*)(newDataPtr+diffedObjectOffset) = variableID; // copy over the variableID
     400          diffedObjectOffset += sizeof(VariableID);
     401          memcpy( newDataPtr+diffedObjectOffset, origDataPtr+objectOffset, varSize );
     402          diffedObjectOffset += varSize;
     403          objectOffset += varSize;
     404        }
     405        else
     406        {
     407          objectOffset += varSize;
     408        }
     409      }
     410
     411      ++variableID;
     412      ++sizes;
     413    }
     414   
     415    // if there are variables from this object with 0 size left in sizes
     416    if( Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables() != variableID )
     417      sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables() - variableID;
     418   
     419    newObjectHeader.setDiffed(true);
     420    newObjectHeader.setDataSize(diffedObjectOffset-SynchronisableHeaderLight::getSize());
     421    assert(objectOffset == objectHeader.getDataSize()+SynchronisableHeader::getSize());
     422    assert(newObjectHeader.getDataSize()>0);
     423   
     424    origDataPtr += objectOffset;
     425    baseDataPtr += objectOffset;
     426    newDataPtr += diffedObjectOffset;
     427  }
     428}
     429
     430inline void /*Gamestate::*/copyObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes )
     431{
     432  //       COUT(4) << "docopy" << endl;
     433  // Just copy over the whole Object
     434  memcpy( newData, origData, objectHeader.getDataSize()+SynchronisableHeader::getSize() );
     435  SynchronisableHeader(newData).setDiffed(false);
     436 
     437  newData += objectHeader.getDataSize()+SynchronisableHeader::getSize();
     438  origData += objectHeader.getDataSize()+SynchronisableHeader::getSize();
     439//   SynchronisableHeader baseHeader( baseData );
     440//   baseData += baseHeader.getDataSize()+SynchronisableHeader::getSize();
     441  //       COUT(4) << "copy " << h.getObjectID() << endl;
     442  //       COUT(4) << "copy " << h.getObjectID() << ":";
     443  sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables();
     444//   for( unsigned int i = 0; i < Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables(); ++i )
     445//   {
     446//     //         COUT(4) << " " << *sizes;
     447//     ++sizes;
     448//   }
     449    //       COUT(4) << endl;
     450}
     451
     452inline bool findObject(uint8_t*& dataPtr, uint8_t* endPtr, SynchronisableHeader& objectHeader)
     453{
     454  // Some assertions to make sure the dataPtr is valid (pointing to a SynchronisableHeader)
     455  {
     456    SynchronisableHeader htemp2(dataPtr);
     457    assert(htemp2.getClassID()<500);
     458    assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
     459    assert(htemp2.isDiffed()==false);
     460  }
     461  uint32_t objectID = objectHeader.getObjectID();
     462  while ( dataPtr < endPtr )
     463  {
     464    SynchronisableHeader htemp(dataPtr);
     465    assert( htemp.getDataSize()!=0 );
     466    if ( htemp.getObjectID() == objectID )
     467    {
     468      assert( objectHeader.getClassID() == htemp.getClassID() );
     469      assert( objectHeader.getCreatorID() == htemp.getCreatorID() );
     470      return true;
     471    }
     472    {
     473      if( dataPtr+htemp.getDataSize()+SynchronisableHeader::getSize() < endPtr )
     474      {
     475        SynchronisableHeader htemp2(dataPtr+htemp.getDataSize()+SynchronisableHeader::getSize());
     476        assert(htemp2.getClassID()<500);
     477        assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
     478        assert(htemp2.isDiffed()==false);
     479      }
     480    }
     481    dataPtr += htemp.getDataSize()+SynchronisableHeader::getSize();
     482   
     483  }
     484  assert(dataPtr == endPtr);
     485 
     486  return false;
     487}
     488
    366489Gamestate* Gamestate::diffVariables(Gamestate *base)
    367490{
    368491  assert(this && base); assert(data_ && base->data_);
    369   assert(!header_->isCompressed() && !base->header_->isCompressed());
    370   assert(!header_->isDiffed());
     492  assert(!header_.isCompressed() && !base->header_.isCompressed());
     493  assert(!header_.isDiffed());
     494  assert( header_.getDataSize() && base->header_.getDataSize() );
    371495
    372496
    373497  // *** first do a raw diff of the two gamestates
    374498
    375   uint8_t *baseData = GAMESTATE_START(base->data_);
    376   uint8_t *origData = GAMESTATE_START(this->data_);
    377   uint32_t origLength = header_->getDataSize();
    378   uint32_t baseLength = base->header_->getDataSize();
    379 
    380   assert( origLength && baseLength );
    381 
    382   uint8_t *nData = new uint8_t[origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_]; // this is the maximum size needed in the worst case
    383   uint8_t *dest = GAMESTATE_START(nData);
    384 
    385   uint32_t baseOffset = 0; //offset in the diffed stream
    386   uint32_t origOffset = 0; //offset in the new stream with removed 0's
    387   std::vector<uint32_t>::iterator sizes = this->sizes_.begin();
    388 
    389   while( origOffset < origLength )
     499  uint8_t *baseDataPtr = GAMESTATE_START(base->data_);
     500  uint8_t *origDataPtr = GAMESTATE_START(this->data_);
     501  uint8_t *origDataEnd = origDataPtr + header_.getDataSize();
     502  uint8_t *baseDataEnd = baseDataPtr + base->header_.getDataSize();
     503//   uint32_t origLength = header_.getDataSize();
     504//   uint32_t baseLength = base->header_.getDataSize();
     505
     506  // Allocate new space for diffed gamestate
     507  uint32_t newDataSize = header_.getDataSize() + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_;
     508  uint8_t *newData = new uint8_t[newDataSize]; // this is the maximum size needed in the worst case
     509  uint8_t *destDataPtr = GAMESTATE_START(newData);
     510
     511  std::vector<uint32_t>::iterator sizesIt = this->sizes_.begin();
     512
     513  while( origDataPtr < origDataEnd )
    390514  {
    391515    //iterate through all objects
    392516
    393     SynchronisableHeader h(origData+origOffset);
     517    SynchronisableHeader origHeader(origDataPtr);
    394518
    395519    // Find (if possible) the current object in the datastream of the old gamestate
    396520    // Start at the current offset position
    397     if(baseOffset >= baseLength)
    398       baseOffset = 0;
    399     uint8_t* temp = baseData + baseOffset;
    400     uint32_t objectID = h.getObjectID();
    401     assert(temp < baseData+baseLength);
    402     assert(dest < nData + origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_);
    403     assert(sizes != this->sizes_.end());
    404     while ( temp < baseData+baseLength )
    405     {
    406       SynchronisableHeader htemp(temp);
    407       assert( htemp.getDataSize()!=0 );
    408       if ( htemp.getObjectID() == objectID )
    409       {
    410         assert( h.getClassID() == htemp.getClassID() );
    411         goto DODIFF;
    412       }
    413 //       {
    414 //         SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize());
    415 //         if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength )
    416 //         {
    417 //           assert(htemp2.getClassID()<500);
    418 //           assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
    419 //           assert(htemp2.isDiffed()==false);
    420 //         }
    421 //       }
    422       temp += htemp.getDataSize()+SynchronisableHeader::getSize();
     521    if(baseDataPtr == baseDataEnd)
     522      baseDataPtr = GAMESTATE_START(base->data_);
     523    uint8_t* oldBaseDataPtr = baseDataPtr;
     524   
     525    assert(baseDataPtr < baseDataEnd);
     526    assert(destDataPtr < newData + newDataSize);
     527    assert(sizesIt != this->sizes_.end());
     528   
     529    assert(Synchronisable::getSynchronisable(origHeader.getObjectID()));
     530    assert(ClassByID(origHeader.getClassID()));
     531    assert(origHeader.getDataSize() < 500);
     532   
     533    bool diffedObject = false;
     534    if( findObject(baseDataPtr, baseDataEnd, origHeader) )
     535    {
     536      SynchronisableHeader baseHeader(baseDataPtr);
     537      assert(Synchronisable::getSynchronisable(baseHeader.getObjectID()));
     538      assert(ClassByID(baseHeader.getClassID()));
     539      assert(baseHeader.getDataSize() < 500);
     540      if( SynchronisableHeader(baseDataPtr).getDataSize()==origHeader.getDataSize() )
     541      {
     542//         COUT(4) << "diffing object in order: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
     543        diffObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
     544        diffedObject = true;
     545      }
     546      else
     547      {
     548//         COUT(4) << "copy object because of different data sizes (1): " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
     549        copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
     550        assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd);
     551      }
    423552       
    424553    }
    425     // If not found start looking at the beginning
    426     assert( temp==baseData+baseLength );
    427     temp = baseData;
    428 //     {
    429 //       SynchronisableHeader htemp2(temp);
    430 //       if( temp < baseData+baseLength )
    431 //       {
    432 //         assert(htemp2.getClassID()<500);
    433 //         assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
    434 //         assert(htemp2.isDiffed()==false);
    435 //       }
    436 //     }
    437     while ( temp < baseData+baseOffset )
    438     {
    439       SynchronisableHeader htemp(temp);
    440       if ( htemp.getObjectID() == objectID )
    441       {
    442         assert( h.getClassID() == htemp.getClassID() );
    443         goto DODIFF;
    444       }
    445 //       {
    446 //         SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize());
    447 //         if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength )
    448 //         {
    449 //           assert(htemp2.getClassID()<500);
    450 //           assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
    451 //           assert(htemp2.isDiffed()==false);
    452 //         }
    453 //       }
    454       temp += htemp.getDataSize()+SynchronisableHeader::getSize();
    455     }
    456     // Object is new, thus never transmitted -> just copy over
    457     goto DOCOPY;
    458 
    459 
    460 DODIFF:
    461     {
    462 //       COUT(4) << "dodiff" << endl;
    463 //       if(baseOffset==0)
    464 //       {
    465 //         assert(origOffset==0);
    466 //       }
    467       uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData
    468       // Check whether the whole object stayed the same
    469       if( memcmp( origData+origOffset+objectOffset, temp+objectOffset, h.getDataSize()) == 0 )
    470       {
    471 //         COUT(4) << "skip object" << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl;
    472         origOffset += objectOffset+ h.getDataSize(); // skip the whole object
    473         baseOffset = temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData;
    474         sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables();
     554    else
     555    {
     556      assert( baseDataPtr == baseDataEnd );
     557      baseDataPtr = GAMESTATE_START(base->data_);
     558      if( findObject(baseDataPtr, oldBaseDataPtr, origHeader) )
     559      {
     560        SynchronisableHeader baseHeader(baseDataPtr);
     561        assert(Synchronisable::getSynchronisable(baseHeader.getObjectID()));
     562        assert(ClassByID(baseHeader.getClassID()));
     563        assert(baseHeader.getDataSize() < 500);
     564        if( SynchronisableHeader(baseDataPtr).getDataSize()==origHeader.getDataSize() )
     565        {
     566//           COUT(4) << "diffing object out of order: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
     567          diffObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
     568          diffedObject = true;
     569        }
     570        else
     571        {
     572//           COUT(4) << "copy object because of different data sizes (2): " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
     573          copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
     574          assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd);
     575        }
    475576      }
    476577      else
    477578      {
    478 //         if( Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() == "Bot" )
    479 //           COUT(0) << "blub" << endl;
    480 //         COUT(4) << "object diff: " << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl;
    481 //         COUT(4) << "diff " << h.getObjectID() << ":";
    482         // Now start to diff the Object
    483         SynchronisableHeaderLight h2(dest);
    484         h2 = h; // copy over the objectheader
    485         VariableID variableID = 0;
    486         uint32_t newObjectOffset = SynchronisableHeaderLight::getSize();
    487         // iterate through all variables
    488         while( objectOffset < h.getDataSize()+SynchronisableHeader::getSize() )
    489         {
    490           // check whether variable changed and write id and copy over variable to the new stream
    491           // otherwise skip variable
    492           assert(sizes != this->sizes_.end());
    493           uint32_t varSize = *sizes;
    494           assert( varSize == Synchronisable::getSynchronisable(h.getObjectID())->getVarSize(variableID) );
    495           if ( varSize != 0 )
    496           {
    497             if ( memcmp(origData+origOffset+objectOffset, temp+objectOffset, varSize) != 0 )
    498             {
    499 //               COUT(4) << "copy variable" << endl;
    500               *(VariableID*)(dest+newObjectOffset) = variableID; // copy over the variableID
    501               newObjectOffset += sizeof(VariableID);
    502               memcpy( dest+newObjectOffset, origData+origOffset+objectOffset, varSize );
    503               newObjectOffset += varSize;
    504               objectOffset += varSize;
    505             }
    506             else
    507             {
    508 //               COUT(4) << "skip variable" << endl;
    509               objectOffset += varSize;
    510             }
    511           }
    512 //           else
    513 //             COUT(4) << "varsize 0" << endl;
    514 
    515           ++variableID;
    516           ++sizes;
    517         }
    518        
    519         if( Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() != variableID )
    520           sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() - variableID;
    521 //         COUT(4) << endl;
    522         h2.setDiffed(true);
    523         h2.setDataSize(newObjectOffset-SynchronisableHeaderLight::getSize());
    524         assert(objectOffset == h.getDataSize()+SynchronisableHeader::getSize());
    525         origOffset += objectOffset;
    526 //         baseOffset += temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData;
    527         //baseOffset += objectOffset;
    528 //         SynchronisableHeader htemp(temp);
    529 //         baseOffset += SynchronisableHeader::getSize() + htemp.getDataSize();
    530 //         {
    531 //           SynchronisableHeader htemp2( baseData+(temp-baseData+objectOffset) );
    532 //           if( baseData+(temp-baseData+objectOffset) < baseData+baseLength )
    533 //           {
    534 //             assert(htemp2.getClassID()<500);
    535 //             assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
    536 //             assert(htemp2.isDiffed()==false);
    537 //           }
    538 //         }
    539         baseOffset = temp-baseData + objectOffset;
    540         dest += newObjectOffset;
    541       }
    542 
    543       continue;
    544     }
    545 
    546 DOCOPY:
    547     {
    548 //       COUT(4) << "docopy" << endl;
    549       // Just copy over the whole Object
    550       memcpy( dest, origData+origOffset, h.getDataSize()+SynchronisableHeader::getSize() );
    551       dest += h.getDataSize()+SynchronisableHeader::getSize();
    552       origOffset += h.getDataSize()+SynchronisableHeader::getSize();
    553       assert( Synchronisable::getSynchronisable(h.getObjectID()) );
    554 //       COUT(4) << "copy " << h.getObjectID() << endl;
    555 //       COUT(4) << "copy " << h.getObjectID() << ":";
    556       //sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables();
    557       for( unsigned int i = 0; i < Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); ++i )
    558       {
    559 //         COUT(4) << " " << *sizes;
    560         ++sizes;
    561       }
    562 //       COUT(4) << endl;
    563       assert(sizes != this->sizes_.end() || origOffset>=origLength);
    564       continue;
    565     }
    566   }
    567 
    568 
    569   Gamestate *g = new Gamestate(nData, getClientID());
    570   assert(g->header_);
    571   *(g->header_) = *header_;
    572   g->header_->setBaseID( base->getID() );
    573   g->header_->setDataSize(dest - nData - GamestateHeader::getSize());
     579//         COUT(4) << "copy object: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
     580        assert(baseDataPtr == oldBaseDataPtr);
     581        copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
     582        assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd);
     583      }
     584    }
     585  }
     586  assert(sizesIt==this->sizes_.end());
     587
     588
     589  Gamestate *g = new Gamestate(newData, getPeerID());
     590  (g->header_) = header_;
     591  g->header_.setBaseID( base->getID() );
     592  g->header_.setDataSize(destDataPtr - newData - GamestateHeader::getSize());
    574593  g->flags_=flags_;
    575594  g->packetDirection_ = packetDirection_;
     
    579598
    580599
    581 Gamestate* Gamestate::diffData(Gamestate *base)
     600/*Gamestate* Gamestate::diffData(Gamestate *base)
    582601{
    583602  assert(this && base); assert(data_ && base->data_);
    584   assert(!header_->isCompressed() && !base->header_->isCompressed());
    585   assert(!header_->isDiffed());
     603  assert(!header_.isCompressed() && !base->header_.isCompressed());
     604  assert(!header_.isDiffed());
    586605
    587606  uint8_t *basep = GAMESTATE_START(base->data_);
    588607  uint8_t *gs = GAMESTATE_START(this->data_);
    589   uint32_t dest_length = header_->getDataSize();
     608  uint32_t dest_length = header_.getDataSize();
    590609
    591610  if(dest_length==0)
     
    595614  uint8_t *dest = GAMESTATE_START(ndata);
    596615
    597   rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
     616  rawDiff( dest, gs, basep, header_.getDataSize(), base->header_.getDataSize() );
    598617#ifndef NDEBUG
    599618  uint8_t *dest2 = new uint8_t[dest_length];
    600   rawDiff( dest2, dest, basep, header_->getDataSize(), base->header_->getDataSize() );
     619  rawDiff( dest2, dest, basep, header_.getDataSize(), base->header_.getDataSize() );
    601620  assert( memcmp( dest2, gs, dest_length) == 0 );
    602621  delete dest2;
     
    606625  assert(g->header_);
    607626  *(g->header_) = *header_;
    608   g->header_->setDiffed( true );
    609   g->header_->setBaseID( base->getID() );
     627  g->header_.setDiffed( true );
     628  g->header_.setBaseID( base->getID() );
    610629  g->flags_=flags_;
    611630  g->packetDirection_ = packetDirection_;
     
    619638{
    620639  assert(this && base); assert(data_ && base->data_);
    621   assert(!header_->isCompressed() && !base->header_->isCompressed());
    622   assert(header_->isDiffed());
     640  assert(!header_.isCompressed() && !base->header_.isCompressed());
     641  assert(header_.isDiffed());
    623642
    624643  uint8_t *basep = GAMESTATE_START(base->data_);
    625644  uint8_t *gs = GAMESTATE_START(this->data_);
    626   uint32_t dest_length = header_->getDataSize();
     645  uint32_t dest_length = header_.getDataSize();
    627646
    628647  if(dest_length==0)
     
    632651  uint8_t *dest = ndata + GamestateHeader::getSize();
    633652
    634   rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
     653  rawDiff( dest, gs, basep, header_.getDataSize(), base->header_.getDataSize() );
    635654
    636655  Gamestate *g = new Gamestate(ndata, getClientID());
    637656  assert(g->header_);
    638657  *(g->header_) = *header_;
    639   g->header_->setDiffed( false );
     658  g->header_.setDiffed( false );
    640659  g->flags_=flags_;
    641660  g->packetDirection_ = packetDirection_;
     
    670689  }
    671690  assert(j==datalength);
    672 }
    673 
    674 
    675 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
     691}*/
     692
     693
     694/*Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
    676695  assert(data_);
    677696  std::list<obj>::iterator it;
    678697
    679698  // allocate memory for new data
    680   uint8_t *gdata = new uint8_t[header_->getDataSize()+GamestateHeader::getSize()];
     699  uint8_t *gdata = new uint8_t[header_.getDataSize()+GamestateHeader::getSize()];
    681700  // create a gamestate out of it
    682701  Gamestate *gs = new Gamestate(gdata);
     
    694713
    695714  //call TrafficControl
    696   TrafficControl::getInstance()->processObjectList( clientID, header_->getID(), dataVector_ );
     715  TrafficControl::getInstance()->processObjectList( clientID, header_.getID(), dataVector_ );
    697716
    698717  //copy in the zeros
     
    725744#ifndef NDEBUG
    726745  uint32_t origsize = destsize;
    727   while ( origsize < header_->getDataSize() )
     746  while ( origsize < header_.getDataSize() )
    728747  {
    729748    SynchronisableHeader oldobjectheader(origdata);
     
    732751    origsize += objectsize;
    733752  }
    734   assert(origsize==header_->getDataSize());
     753  assert(origsize==header_.getDataSize());
    735754  assert(destsize!=0);
    736755#endif
    737   gs->header_->setDataSize( destsize );
     756  gs->header_.setDataSize( destsize );
    738757  return gs;
    739 }
    740 
    741 
    742 uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
     758}*/
     759
     760
     761uint32_t Gamestate::calcGamestateSize(uint32_t id, uint8_t mode)
    743762{
    744763  uint32_t size = 0;
  • code/trunk/src/libraries/network/packet/Gamestate.h

    r7163 r7801  
    4242#include "Packet.h"
    4343
    44 namespace orxonox {
     44namespace orxonox
     45{
    4546
    46 namespace packet {
     47namespace packet
     48{
     49   
     50static const uint8_t GAMESTATE_MODE_SERVER = 0x1;
     51static const uint8_t GAMESTATE_MODE_CLIENT = 0x2;
    4752
    48 class _NetworkExport GamestateHeader{
     53class _NetworkExport GamestateHeader
     54{
    4955  public:
    50     GamestateHeader(uint8_t *data){ assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; }
    51     GamestateHeader(uint8_t *data, GamestateHeader* h)
    52     { assert(data); data_=data; memcpy(data_, h->data_, getSize()); }
     56    GamestateHeader(){ data_=0; }
     57    GamestateHeader(uint8_t* data)
     58      { assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; }
     59    /*GamestateHeader(uint8_t* data, GamestateHeader* h)
     60      { assert(data); data_=data; memcpy(data_, h->data_, getSize()); }*/
     61    void setData(uint8_t* data)
     62      { assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; }
    5363    static inline uint32_t getSize()
    54     { return 21; }
     64      { return 21; }
    5565
    56     inline int32_t getID() const
    57     { assert(data_); return *(int32_t*)(data_+4); }
    58     inline void setID(int32_t id)
    59     { assert(data_); *(int32_t*)(data_+4) = id; }
     66    inline uint32_t getID() const
     67      { assert(data_); return *(uint32_t*)(data_+4); }
     68    inline void setID(uint32_t id)
     69      { assert(data_); *(uint32_t*)(data_+4) = id; }
    6070
    61     inline int32_t getBaseID() const
    62     { assert(data_); return *(int32_t*)(data_+8); }
    63     inline void setBaseID(int32_t id)
    64     { assert(data_); *(int32_t*)(data_+8) = id; }
     71    inline uint32_t getBaseID() const
     72      { assert(data_); return *(uint32_t*)(data_+8); }
     73    inline void setBaseID(uint32_t id)
     74      { assert(data_); *(uint32_t*)(data_+8) = id; }
    6575
    6676    inline uint32_t getDataSize() const
    67     { assert(data_); return *(uint32_t*)(data_+12); }
     77      { assert(data_); return *(uint32_t*)(data_+12); }
    6878    inline void setDataSize(uint32_t size)
    69     { assert(data_); *(uint32_t*)(data_+12) = size; }
     79      { assert(data_); *(uint32_t*)(data_+12) = size; }
    7080
    7181    inline uint32_t getCompSize() const
     
    7585
    7686    inline bool isDiffed() const
    77     { assert(data_); return *(int8_t*)(data_+20) & 0x1; }
     87      { assert(data_); return *(int8_t*)(data_+20) & 0x1; }
    7888    inline void setDiffed(bool b)
    79     { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); }
     89      { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); }
    8090
    8191    inline bool isComplete() const
    82     { assert(data_); return *(int8_t*)(data_+20) & 0x2; }
     92      { assert(data_); return *(int8_t*)(data_+20) & 0x2; }
    8393    inline void setComplete(bool b)
    84     { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); }
     94      { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); }
    8595
    8696    inline bool isCompressed() const
    87     { assert(data_); return *(int8_t*)(data_+20) & 0x4; }
     97      { assert(data_); return *(int8_t*)(data_+20) & 0x4; }
    8898    inline void setCompressed(bool b)
    89     { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); }
     99      { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); }
    90100
    91101    inline void operator=(GamestateHeader& h)
    92     { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); }
     102      { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); }
    93103  private:
    94     uint8_t *data_;
     104    uint8_t* data_;
    95105
    96106};
     
    99109    @author Oliver Scheuss
    100110*/
    101 class _NetworkExport Gamestate: public Packet{
     111class _NetworkExport Gamestate: public Packet
     112{
    102113  public:
    103114    Gamestate();
     
    110121    bool collectData(int id, uint8_t mode=0x0);
    111122    bool spreadData( uint8_t mode=0x0);
    112     inline int32_t getID() const { return header_->getID(); }
    113     inline bool isDiffed() const { return header_->isDiffed(); }
    114     inline bool isCompressed() const { return header_->isCompressed(); }
    115     inline int32_t getBaseID() const { return header_->getBaseID(); }
    116     inline uint32_t getDataSize() const { return header_->getDataSize(); }
     123    inline uint32_t getID() const { return header_.getID(); }
     124    inline bool isDiffed() const { return header_.isDiffed(); }
     125    inline bool isCompressed() const { return header_.isCompressed(); }
     126    inline int32_t getBaseID() const { return header_.getBaseID(); }
     127    inline uint32_t getDataSize() const { return header_.getDataSize(); }
    117128    Gamestate* diffVariables(Gamestate *base);
    118     Gamestate* diffData(Gamestate *base);
    119     Gamestate *undiff(Gamestate *base);
    120     Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
     129//     Gamestate* diffData(Gamestate *base);
     130//     Gamestate *undiff(Gamestate *base);
     131//     Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
    121132    bool compressData();
    122133    bool decompressData();
     
    125136    // Packet functions
    126137  private:
    127     void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
    128     inline uint32_t findObject( const SynchronisableHeader& header, uint8_t* mem, uint32_t dataLength, uint32_t startPosition = 0 );
     138//     void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
     139//     inline uint32_t findObject( const SynchronisableHeader& header, uint8_t* mem, uint32_t dataLength, uint32_t startPosition = 0 );
    129140    virtual uint32_t getSize() const;
    130     virtual inline bool process();
    131     uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0);
     141    virtual bool process(orxonox::Host* host);
     142    uint32_t calcGamestateSize(uint32_t id, uint8_t mode=0x0);
     143//     inline void diffObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes );
     144//     inline void copyObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes );
    132145   
    133146    std::list<obj>          dataVector_;
    134     GamestateHeader*        header_;
     147    GamestateHeader         header_;
    135148    std::vector<uint32_t>   sizes_;
    136149    uint32_t                nrOfVariables_;
  • code/trunk/src/libraries/network/packet/Packet.cc

    r7163 r7801  
    3535#include <enet/enet.h>
    3636#include <boost/static_assert.hpp>
     37#include <boost/thread/mutex.hpp>
    3738
    3839#include "util/Debug.h"
     
    5354
    5455// Make sure we assume the right values
    55 BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Reliable)   == static_cast<int>(ENET_PACKET_FLAG_RELIABLE));
    56 BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Unsequence) == static_cast<int>(ENET_PACKET_FLAG_UNSEQUENCED));
    57 BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::NoAllocate) == static_cast<int>(ENET_PACKET_FLAG_NO_ALLOCATE));
     56BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Reliable)    == static_cast<int>(ENET_PACKET_FLAG_RELIABLE));
     57BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Unsequenced) == static_cast<int>(ENET_PACKET_FLAG_UNSEQUENCED));
     58BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::NoAllocate)  == static_cast<int>(ENET_PACKET_FLAG_NO_ALLOCATE));
    5859
    5960#define PACKET_FLAG_DEFAULT PacketFlag::NoAllocate
     
    6162
    6263std::map<size_t, Packet *> Packet::packetMap_;
     64boost::mutex Packet::packetMapMutex_;
    6365
    6466Packet::Packet()
     
    6668  flags_ = PACKET_FLAG_DEFAULT;
    6769  packetDirection_ = Direction::Outgoing;
    68   clientID_=0;
     70  peerID_=0;
    6971  data_=0;
    7072  enetPacket_=0;
     
    7274}
    7375
    74 Packet::Packet(uint8_t *data, unsigned int clientID)
     76Packet::Packet(uint8_t *data, unsigned int peerID)
    7577{
    7678  flags_ = PACKET_FLAG_DEFAULT;
    7779  packetDirection_ = Direction::Incoming;
    78   clientID_=clientID;
     80  peerID_=peerID;
    7981  data_=data;
    8082  enetPacket_=0;
     
    8789  flags_=p.flags_;
    8890  packetDirection_ = p.packetDirection_;
    89   clientID_ = p.clientID_;
     91  peerID_ = p.peerID_;
    9092  if(p.data_){
    9193    data_ = new uint8_t[p.getSize()];
     
    123125}
    124126
    125 bool Packet::send(){
     127bool Packet::send(orxonox::Host* host){
    126128  if(packetDirection_ != Direction::Outgoing && packetDirection_ != Direction::Bidirectional ){
    127129    assert(0);
     
    142144      // Assures we don't create a packet and destroy it right after in another thread
    143145      // without having a reference in the packetMap_
     146      Packet::packetMapMutex_.lock();
    144147      packetMap_[reinterpret_cast<size_t>(enetPacket_)] = this;
     148      Packet::packetMapMutex_.unlock();
    145149    }
    146150  }
     
    164168//  ENetPacket *temp = enetPacket_;
    165169//  enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
    166   if(!Host::addPacket( enetPacket_, clientID_))
    167     enet_packet_destroy(this->enetPacket_); // if we could not add the packet to the enet queue delete it manually
     170  if( this->flags_ & PacketFlag::Reliable )
     171    host->addPacket( enetPacket_, peerID_, NETWORK_CHANNEL_DEFAULT);
     172  else
     173    host->addPacket( enetPacket_, peerID_, NETWORK_CHANNEL_UNRELIABLE);
    168174  return true;
    169175}
     
    172178  uint8_t *data = packet->data;
    173179  assert(ClientInformation::findClient(&peer->address)->getID() != static_cast<unsigned int>(-2) || !Host::isServer());
    174   unsigned int clientID = ClientInformation::findClient(&peer->address)->getID();
     180  unsigned int peerID = ClientInformation::findClient(&peer->address)->getID();
     181  // HACK
     182  if( peerID==static_cast<unsigned int>(-2))
     183    peerID = NETWORK_PEER_ID_SERVER;
    175184  Packet *p = 0;
    176   COUT(6) << "packet type: " << *(Type::Value *)&data[_PACKETID] << std::endl;
     185//   COUT(6) << "packet type: " << *(Type::Value *)&data[_PACKETID] << std::endl;
    177186  switch( *(Type::Value *)(data + _PACKETID) )
    178187  {
    179188    case Type::Acknowledgement:
    180       COUT(5) << "ack" << std::endl;
    181       p = new Acknowledgement( data, clientID );
     189//       COUT(5) << "ack" << std::endl;
     190    p = new Acknowledgement( data, peerID );
    182191      break;
    183192    case Type::Chat:
    184       COUT(5) << "chat" << std::endl;
    185       p = new Chat( data, clientID );
     193//       COUT(5) << "chat" << std::endl;
     194      p = new Chat( data, peerID );
    186195      break;
    187196    case Type::ClassID:
    188       COUT(5) << "classid" << std::endl;
    189       p = new ClassID( data, clientID );
     197//       COUT(5) << "classid" << std::endl;
     198      p = new ClassID( data, peerID );
    190199      break;
    191200    case Type::Gamestate:
    192       COUT(5) << "gamestate" << std::endl;
    193       // TODO: remove brackets
    194       p = new Gamestate( data, clientID );
     201//       COUT(5) << "gamestate" << std::endl;
     202      p = new Gamestate( data, peerID );
    195203      break;
    196204    case Type::Welcome:
    197       COUT(5) << "welcome" << std::endl;
    198       p = new Welcome( data, clientID );
     205//       COUT(5) << "welcome" << std::endl;
     206      p = new Welcome( data, peerID );
    199207      break;
    200208    case Type::DeleteObjects:
    201       COUT(5) << "deleteobjects" << std::endl;
    202       p = new DeleteObjects( data, clientID );
     209//       COUT(5) << "deleteobjects" << std::endl;
     210      p = new DeleteObjects( data, peerID );
    203211      break;
    204212    case Type::FunctionCalls:
    205       COUT(5) << "functionCalls" << std::endl;
    206       p = new FunctionCalls( data, clientID );
     213//       COUT(5) << "functionCalls" << std::endl;
     214      p = new FunctionCalls( data, peerID );
    207215      break;
    208216    case Type::FunctionIDs:
    209       COUT(5) << "functionIDs" << std::endl;
    210       p = new FunctionIDs( data, clientID );
     217//       COUT(5) << "functionIDs" << std::endl;
     218      p = new FunctionIDs( data, peerID );
    211219      break;
    212220    default:
    213       assert(0); //TODO: repair this
     221      assert(0);
    214222      break;
    215223  }
     
    229237void Packet::deletePacket(ENetPacket *enetPacket){
    230238  // Get our Packet from a global map with all Packets created in the send() method of Packet.
     239  Packet::packetMapMutex_.lock();
    231240  std::map<size_t, Packet*>::iterator it = packetMap_.find(reinterpret_cast<size_t>(enetPacket));
    232241  assert(it != packetMap_.end());
     
    235244  delete it->second;
    236245  packetMap_.erase(it);
    237   COUT(6) << "PacketMap size: " << packetMap_.size() << std::endl;
     246  Packet::packetMapMutex_.unlock();
     247//   COUT(6) << "PacketMap size: " << packetMap_.size() << std::endl;
    238248}
    239249
  • code/trunk/src/libraries/network/packet/Packet.h

    r7490 r7801  
    6868    virtual unsigned char *getData(){ return data_; };
    6969    virtual unsigned int getSize() const =0;
    70     virtual bool process()=0;
     70    virtual bool process(orxonox::Host* host)=0;
    7171    inline uint32_t getFlags()
    7272      { return flags_; }
    73     inline int getClientID()
    74       { return clientID_; }
    75     inline void setClientID( int id )
    76       { clientID_ = id; }
     73    inline int getPeerID()
     74      { return peerID_; }
     75    inline void setPeerID( int id )
     76      { peerID_ = id; }
     77    inline bool isReliable()
     78      { return this->flags_ & PacketFlag::Reliable; }
     79    inline uint32_t getRequiredGamestateID()
     80      { return this->requiredGamestateID_; }
    7781
    78     virtual bool send();
     82    virtual bool send(orxonox::Host* host);
    7983  protected:
    8084    Packet();
    81     Packet(uint8_t *data, unsigned int clientID);
     85    Packet(uint8_t *data, unsigned int peerID);
    8286//    Packet(ENetPacket *packet, ENetPeer *peer);
    8387    inline bool isDataENetAllocated() const
     
    8589
    8690    uint32_t flags_;
    87     unsigned int clientID_;
     91    unsigned int peerID_;
     92    uint32_t requiredGamestateID_;
    8893    Direction::Value packetDirection_;
    8994    /** Pointer to the data. Be careful when deleting it because it might
     
    96101  private:
    97102    static std::map<size_t, Packet *> packetMap_;
     103    static boost::mutex               packetMapMutex_;
    98104    ENetPacket *enetPacket_;
    99105};
  • code/trunk/src/libraries/network/packet/ServerInformation.cc

    r7461 r7801  
    2121 *
    2222 *   Author:
    23  *      Fabian 'x3n' Landau
     23 *      Oliver Scheuss
    2424 *   Co-authors:
    2525 *      ...
     
    5858      char* ack = new char[strlen(LAN_DISCOVERY_ACK)+1];
    5959      loadAndIncrease((char*&)ack, temp);
    60       assert(strcmp(ack, (const char*)LAN_DISCOVERY_ACK)==0);
     60
     61      /* Fabian, what is this used for? it crashes the masterserver, hence commenting it */
     62      // written by Oli: this is just to make sure that loadAndIncrease really writes the whole ACK string into char* ack
     63//       assert(strcmp(ack, (const char*)LAN_DISCOVERY_ACK)==0);
     64
    6165      // Save Server Name
    6266      loadAndIncrease(this->serverName_, temp);
  • code/trunk/src/libraries/network/packet/ServerInformation.h

    r7459 r7801  
    2121 *
    2222 *   Author:
    23  *      Fabian 'x3n' Landau
     23 *      Oliver Scheuss
    2424 *   Co-authors:
    2525 *      ...
     
    5050        std::string   getServerName() { return this->serverName_; }
    5151        void          setServerName(std::string name) { this->serverName_ = name; }
     52        void          setServerIP( std::string IP ) { this->serverIP_ = IP; }
    5253        uint32_t      getServerRTT() { return this->serverRTT_; }
    5354       
  • code/trunk/src/libraries/network/packet/Welcome.cc

    r5781 r7801  
    7373}
    7474
    75 bool Welcome::process(){
     75bool Welcome::process(orxonox::Host* host){
    7676  uint32_t clientID;
    7777  clientID = *(uint32_t *)(data_ + _CLIENTID );
    7878  assert(*(uint32_t *)(data_ + _ENDIANTEST ) == 0xFEDC4321);
    79   Host::setClientID(clientID);
     79  host->setClientID(clientID);
    8080  COUT(3) << "Welcome set clientId: " << clientID << endl;
    8181  Synchronisable::setClient(true);
  • code/trunk/src/libraries/network/packet/Welcome.h

    r6073 r7801  
    4747  uint8_t *getData();
    4848  inline unsigned int getSize() const;
    49   bool process();
     49  virtual bool process(orxonox::Host* host);
    5050
    5151private:
  • code/trunk/src/libraries/network/synchronisable/Synchronisable.cc

    r7401 r7801  
    123123  {
    124124    SynchronisableHeader header(mem);
    125     assert( !header.isDiffed() );
     125    if( header.isDiffed() )
     126    {
     127      mem += header.getDataSize() + header.getSize();
     128      return 0;
     129    }
     130//     assert( !header.isDiffed() );
    126131
    127132    COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl;
     
    217222   * length of varx: size saved int syncvarlist
    218223   * @param mem pointer to allocated memory with enough size
    219    * @param sizes FIXME - add doc!
     224   * @param sizes vector containing sizes of all objects in gamestate (to be appended)
    220225   * @param id gamestateid of the gamestate to be saved (important for priorities)
    221226   * @param mode defines the direction in which the data will be send/received
    222227   *             0x1: server->client
    223    *             0x2: client->server (not recommended)
     228   *             0x2: client->server
    224229   *             0x3: bidirectional
    225230   * @return true: if !doSync or if everything was successfully saved
     
    265270      //tempsize += (*i)->getSize( mode );
    266271    }
     272    assert(tempsize!=0);  // if this happens an empty object (with no variables) would be transmitted
    267273//     COUT(4) << endl;
    268274
     
    316322      mem += SynchronisableHeader::getSize();
    317323      std::vector<SynchronisableVariableBase *>::iterator i;
    318       for(i=syncList_.begin(); i!=syncList_.end(); i++)
     324      for(i=syncList_.begin(); i!=syncList_.end(); ++i)
    319325      {
    320326        assert( mem <= data+syncHeader2.getDataSize()+SynchronisableHeader::getSize() ); // always make sure we don't exceed the datasize in our stream
  • code/trunk/src/libraries/network/synchronisable/Synchronisable.h

    r7163 r7801  
    6565    };
    6666  }
    67  
    68   typedef uint8_t VariableID;
    69 
    70   /**
    71    * @brief: stores information about a Synchronisable
    72    *
    73    * This class stores the information about a Synchronisable (objectID_, classID_, creatorID_, dataSize)
    74    * in an emulated bitset.
    75    * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
    76    * Bit 32 is a bool and defines whether the variables are stored in diff mode
    77    * Byte 5 to 8: objectID_
    78    * Byte 9 to 12: classID_
    79    * Byte 13 to 16: creatorID_
    80    */
    81   class _NetworkExport SynchronisableHeader{
    82     friend class SynchronisableHeaderLight;
    83     private:
    84       uint8_t* data_;
    85     public:
    86       SynchronisableHeader(uint8_t* data)
    87         { data_ = data; }
    88       inline static uint32_t getSize()
    89         { return 14; }
    90       inline uint16_t getDataSize() const
    91         { return (*(uint16_t*)data_) & 0x7FFF; } //only use the first 15 bits
    92       inline void setDataSize(uint16_t size)
    93         { *(uint16_t*)(data_) = (size & 0x7FFF) | (*(uint16_t*)(data_) & 0x8000 ); }
    94       inline bool isDiffed() const
    95         { return ( (*(uint16_t*)data_) & 0x8000 ) == 0x8000; }
    96       inline void setDiffed( bool b)
    97         { *(uint16_t*)(data_) = (b << 15) | (*(uint16_t*)(data_) & 0x7FFF ); }
    98       inline uint32_t getObjectID() const
    99         { return *(uint32_t*)(data_+2); }
    100       inline void setObjectID(uint32_t objectID_)
    101         { *(uint32_t*)(data_+2) = objectID_; }
    102       inline uint32_t getClassID() const
    103         { return *(uint32_t*)(data_+6); }
    104       inline void setClassID(uint32_t classID_)
    105         { *(uint32_t*)(data_+6) = classID_; }
    106       inline uint32_t getCreatorID() const
    107         { return *(uint32_t*)(data_+10); }
    108       inline void setCreatorID(uint32_t creatorID_)
    109         { *(uint32_t*)(data_+10) = creatorID_; }
    110       inline void operator=(SynchronisableHeader& h)
    111         { memcpy(data_, h.data_, getSize()); }
    112   };
    11367
    11468    /**
     
    12175   * Byte 5 to 8: objectID_
    12276   */
    123   class _NetworkExport SynchronisableHeaderLight{
    124     private:
     77  class _NetworkExport SynchronisableHeaderLight
     78  {
     79    protected:
    12580      uint8_t* data_;
    12681    public:
     
    14196      inline void setObjectID(uint32_t objectID_)
    14297        { *(uint32_t*)(data_+2) = objectID_; }
     98      inline void operator=(SynchronisableHeaderLight& h)
     99        { memcpy(data_, h.data_, SynchronisableHeaderLight::getSize()); }
     100  };
     101 
     102  typedef uint8_t VariableID;
     103 
     104  /**
     105   * @brief: stores information about a Synchronisable
     106   *
     107   * This class stores the information about a Synchronisable (objectID_, classID_, creatorID_, dataSize)
     108   * in an emulated bitset.
     109   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
     110   * Bit 32 is a bool and defines whether the variables are stored in diff mode
     111   * Byte 5 to 8: objectID_
     112   * Byte 9 to 12: classID_
     113   * Byte 13 to 16: creatorID_
     114   */
     115  class _NetworkExport SynchronisableHeader: public SynchronisableHeaderLight
     116  {
     117    public:
     118      SynchronisableHeader(uint8_t* data): SynchronisableHeaderLight(data)
     119        {}
     120      inline static uint32_t getSize()
     121        { return SynchronisableHeaderLight::getSize()+8; }
     122      inline uint32_t getClassID() const
     123        { return *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()); }
     124      inline void setClassID(uint32_t classID_)
     125        { *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()) = classID_; }
     126      inline uint32_t getCreatorID() const
     127        { return *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()+4); }
     128      inline void setCreatorID(uint32_t creatorID_)
     129        { *(uint32_t*)(data_+SynchronisableHeaderLight::getSize()+4) = creatorID_; }
    143130      inline void operator=(SynchronisableHeader& h)
    144131        { memcpy(data_, h.data_, getSize()); }
    145132  };
     133 
     134//   inline void operator=(SynchronisableHeaderLight& h1, SynchronisableHeader& h2)
     135//   {
     136//     memcpy(h1.data_, h2.data_, h1.getSize());
     137//   }
    146138
    147139  /**
  • code/trunk/src/libraries/util/SignalHandler.cc

    r7457 r7801  
    5151#include <X11/Xutil.h>
    5252#include <X11/keysym.h>
     53#include <sys/prctl.h>
    5354
    5455namespace orxonox
     
    137138      COUT(0) << "Received signal " << sigName.c_str() << std::endl << "Try to write backtrace to file orxonox_crash.log" << std::endl;
    138139
    139       int sigPipe[2];
    140       if ( pipe(sigPipe) == -1 )
    141       {
    142         perror("pipe failed!\n");
    143         exit(EXIT_FAILURE);
    144       }
    145 
    146       int sigPid = fork();
    147 
    148       if ( sigPid == -1 )
    149       {
    150         perror("fork failed!\n");
    151         exit(EXIT_FAILURE);
    152       }
    153 
    154       // gdb will be attached to this process
    155       if ( sigPid == 0 )
    156       {
    157         getInstance().dontCatch();
    158         // wait for message from parent when it has attached gdb
    159         int someData;
    160 
    161         read( sigPipe[0], &someData, sizeof(someData) );
    162 
    163         if ( someData != 0x12345678 )
    164         {
    165           COUT(0) << "something went wrong :(" << std::endl;
    166         }
    167 
    168         return;
    169       }
    170 
     140     
     141      // First start GDB which will be attached to this process later on
     142     
    171143      int gdbIn[2];
    172144      int gdbOut[2];
    173145      int gdbErr[2];
    174 
     146     
    175147      if ( pipe(gdbIn) == -1 || pipe(gdbOut) == -1 || pipe(gdbErr) == -1 )
    176148      {
    177149        perror("pipe failed!\n");
    178         kill( sigPid, SIGTERM );
    179         waitpid( sigPid, NULL, 0 );
    180150        exit(EXIT_FAILURE);
    181151      }
    182 
     152     
    183153      int gdbPid = fork();
    184154      // this process will run gdb
    185 
     155     
    186156      if ( gdbPid == -1 )
    187157      {
    188158        perror("fork failed\n");
    189         kill( sigPid, SIGTERM );
    190         waitpid( sigPid, NULL, 0 );
    191159        exit(EXIT_FAILURE);
    192160      }
    193 
     161     
    194162      if ( gdbPid == 0 )
    195163      {
    196164        // start gdb
    197 
     165       
    198166        close(gdbIn[1]);
    199167        close(gdbOut[0]);
    200168        close(gdbErr[0]);
    201 
     169       
    202170        dup2( gdbIn[0], STDIN_FILENO );
    203171        dup2( gdbOut[1], STDOUT_FILENO );
    204172        dup2( gdbErr[1], STDERR_FILENO );
    205 
     173       
    206174        execlp( "sh", "sh", "-c", "gdb", static_cast<void*>(NULL));
     175      }
     176     
     177     
     178      // Now start a fork of this process on which GDB will be attached on
     179     
     180      int sigPipe[2];
     181      if ( pipe(sigPipe) == -1 )
     182      {
     183        perror("pipe failed!\n");
     184        kill( gdbPid, SIGTERM );
     185        waitpid( gdbPid, NULL, 0 );
     186        exit(EXIT_FAILURE);
     187      }
     188
     189      int sigPid = fork();
     190
     191      if ( sigPid == -1 )
     192      {
     193        perror("fork failed!\n");
     194        kill( gdbPid, SIGTERM );
     195        waitpid( gdbPid, NULL, 0 );
     196        exit(EXIT_FAILURE);
     197      }
     198
     199      // gdb will be attached to this process
     200      if ( sigPid == 0 )
     201      {
     202        getInstance().dontCatch();
     203       
     204        // make sure gdb is allowed to attach to our PID even if there are some system restrictions
     205#ifdef PR_SET_PTRACER
     206        if( prctl(PR_SET_PTRACER, gdbPid, 0, 0, 0) == -1 )
     207          COUT(0) << "could not set proper permissions for GDB to attach to process..." << endl;
     208#endif
     209       
     210        // wait for message from parent when it has attached gdb
     211        int someData;
     212
     213        if( read( sigPipe[0], &someData, sizeof(someData) ) != sizeof(someData) )
     214          COUT(0) << "something went wrong :(" << std::endl;
     215
     216        if ( someData != 0x12345678 )
     217        {
     218          COUT(0) << "something went wrong :(" << std::endl;
     219        }
     220
     221        return;
    207222      }
    208223
  • code/trunk/src/modules/objects/ForceField.cc

    r7677 r7801  
    6060        this->setLength(2000);
    6161        this->mode_ = forceFieldMode::tube;
     62       
     63        this->registerVariables();
    6264    }
    6365
     
    8385        XMLPortParam(ForceField, "mode", setMode, getMode, xmlelement, mode);
    8486    }
     87   
     88    void ForceField::registerVariables()
     89    {
     90        registerVariable(this->velocity_, VariableDirection::ToClient);
     91        registerVariable(this->radius_, VariableDirection::ToClient);
     92        registerVariable(this->halfLength_, VariableDirection::ToClient);
     93        registerVariable(this->mode_, VariableDirection::ToClient);
     94    }
     95
    8596
    8697    /**
  • code/trunk/src/modules/objects/ForceField.h

    r7678 r7801  
    8888
    8989            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Creates a ForceField object through XML.
     90            void registerVariables(); //!< Registers the variables that should get synchronised over the network
    9091            virtual void tick(float dt); //!< A method that is called every tick.
     92           
    9193
    9294            /**
     
    141143            float radius_; //!< The radius of the ForceField.
    142144            float halfLength_; //!< Half of the length of the ForceField.
    143             forceFieldMode::Value mode_; //!< The mode of the ForceField.
     145            int mode_; //!< The mode of the ForceField.
    144146  };
    145147}
  • code/trunk/src/modules/overlays/hud/HUDBar.cc

    r7401 r7801  
    8585        this->bar_->setMaterialName(materialname);
    8686
    87         this->value_ = 1.0f;  // initielize with 1.0f to trigger a change when calling setValue(0.0f) on the line below
     87        this->value_ = 1.0f;  // initialize with 1.0f to trigger a change when calling setValue(0.0f) on the line below
    8888        this->setAutoColour(true);
    8989        this->setValue(0.0f); // <--
     
    161161        if (this->right2Left_)
    162162        {
    163             // backward casew
     163            // backward case
    164164            this->bar_->setPosition(0.06f + 0.88f * (1 - this->value_), 0.0f);
    165165            this->bar_->setDimensions(0.88f * this->value_, 1.0f);
  • code/trunk/src/modules/overlays/hud/HUDNavigation.cc

    r7401 r7801  
    2424 *   Co-authors:
    2525 *      Reto Grieder
     26 *      Oliver Scheuss
    2627 *
    2728 */
     
    410411    }
    411412}
    412 }
     413
     414}
  • code/trunk/src/modules/pickup/PickupManager.cc

    r7549 r7801  
    6161    /*static*/ const std::string PickupManager::guiName_s = "PickupInventory";
    6262
    63     // Register static newtork functions that are used to communicate changes to pickups over the network, such that the PickupInventory can display the information about the pickups properly.
     63    // Register static network functions that are used to communicate changes to pickups over the network, such that the PickupInventory can display the information about the pickups properly.
    6464    registerStaticNetworkFunction(PickupManager::pickupChangedUsedNetwork);
    6565    registerStaticNetworkFunction(PickupManager::pickupChangedPickedUpNetwork);
  • code/trunk/src/modules/pickup/PickupSpawner.cc

    r7549 r7801  
    120120    PickupSpawner::~PickupSpawner()
    121121    {
    122         if(this->selfDestruct_ && this->pickup_ != NULL)
     122        if(this->isInitialized() && this->selfDestruct_ && this->pickup_ != NULL)
    123123            this->pickup_->destroy();
    124124    }
     
    317317            assert(pickup);
    318318            assert(target);
    319             assert(pickup->pickup(target));
     319            bool pickedUp = pickup->pickup(target);
     320            assert(pickedUp);
     321            pickedUp = false; // To avoid compiler warning.
    320322
    321323            this->decrementSpawnsRemaining();
  • code/trunk/src/modules/weapons/MuzzleFlash.cc

    r7284 r7801  
    4242        this->setScale(0.1f);
    4343
    44         this->delayTimer_.setTimer(0.1f, false, createExecutor(createFunctor(&MuzzleFlash::destroy, this)));
     44        if( GameMode::isMaster() )
     45          this->delayTimer_.setTimer(0.1f, false, createExecutor(createFunctor(&MuzzleFlash::destroy, this)));
    4546    }
    4647}
  • code/trunk/src/orxonox/LevelManager.cc

    r7724 r7801  
    152152        Ogre::StringVectorPtr levels = Resource::findResourceNames("*.oxw");
    153153        // Iterate over all *.oxw level files.
     154        COUT(3) << "Loading LevelInfos..." << std::endl;
    154155        for (Ogre::StringVector::const_iterator it = levels->begin(); it != levels->end(); ++it)
    155156        {
  • code/trunk/src/orxonox/Main.cc

    r7431 r7801  
    5454    SetCommandLineSwitch(dedicatedClient).information("Start in dedicated client mode");
    5555
     56    /* ADD masterserver command */
     57    SetCommandLineSwitch(masterserver).information("Start in masterserver mode");
     58
    5659    SetCommandLineArgument(generateDoc, "")
    5760        .information("Generates a Doxygen file from things like SetConsoleCommand");
     
    6770        if (CommandLineParser::getValue("generateDoc").getString().empty())
    6871        {
     72            /* TODO make this clear */
    6973            game->setStateHierarchy(
    7074            "root"
     
    7377            "  standalone,server,client"
    7478            "   level"
    75             " server,client"
     79            " server,client,masterserver"
    7680            "  level"
    7781            );
     
    9094            else if (CommandLineParser::getValue("dedicatedClient").getBool())
    9195                Game::getInstance().requestStates("client, level");
     96            /* ADD masterserver command */
     97            else if (CommandLineParser::getValue("masterserver").getBool())
     98                Game::getInstance().requestStates("masterserver");
    9299            else
    93100            {
  • code/trunk/src/orxonox/controllers/ArtificialController.cc

    r7401 r7801  
    6969
    7070        this->target_ = 0;
    71         this->formationFlight_ = true;
     71        this->formationFlight_ = false;
    7272        this->passive_ = false;
    7373        this->maxFormationSize_ = STANDARD_MAX_FORMATION_SIZE;
  • code/trunk/src/orxonox/controllers/NewHumanController.cc

    r7284 r7801  
    375375        {
    376376//             CCOUT(0) << "testing object as target" << endl;
    377             if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" /*&& itr->distance > 500*/)
     377            if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" && itr->distance > 200)
    378378            {
    379379                // Try to cast the user pointer
  • code/trunk/src/orxonox/gamestates/CMakeLists.txt

    r6105 r7801  
    66  GSRoot.cc
    77  GSServer.cc
     8  GSMasterServer.cc
    89  GSStandalone.cc
    910)
  • code/trunk/src/orxonox/gamestates/GSServer.cc

    r7401 r7801  
    3434#include "core/GameMode.h"
    3535#include "network/Server.h"
     36#include "network/Connection.h"
    3637
    3738namespace orxonox
     
    3940    DeclareGameState(GSServer, "server", false, false);
    4041
    41     SetCommandLineArgument(port, 55556).shortcut("p").information("Network communication port to be used 0-65535 (default: 55556)");
     42    SetCommandLineArgument(port, NETWORK_PORT).shortcut("p").information("Network communication port to be used 0-65535 (default: 55556)");
    4243
    4344    GSServer::GSServer(const GameStateInfo& info)
  • code/trunk/src/orxonox/gametypes/Gametype.cc

    r7284 r7801  
    7979        else
    8080            this->scoreboard_ = 0;
     81
     82        /* HACK HACK HACK */
     83        this->dedicatedAddBots_ = createConsoleCommand( "dedicatedAddBots", createExecutor( createFunctor(&Gametype::addBots, this) ) );
     84        this->dedicatedKillBots_ = createConsoleCommand( "dedicatedKillBots", createExecutor( createFunctor(&Gametype::killBots, this) ) );
     85        /* HACK HACK HACK */
    8186    }
    8287
     
    8691        {
    8792            this->gtinfo_->destroy();
     93            if( this->dedicatedAddBots_ )
     94                delete this->dedicatedAddBots_;
     95            if( this->dedicatedKillBots_ )
     96                delete this->dedicatedKillBots_;
    8897        }
    8998    }
  • code/trunk/src/orxonox/gametypes/Gametype.h

    r7284 r7801  
    184184            // Config Values
    185185            std::string scoreboardTemplate_;
     186
     187            /* HACK HACK HACK */
     188            ConsoleCommand* dedicatedAddBots_;
     189            ConsoleCommand* dedicatedKillBots_;
     190            /* HACK HACK HACK */
    186191    };
    187192}
  • code/trunk/src/orxonox/infos/Bot.cc

    r7673 r7801  
    8686            "Alec Trevelyan",
    8787            "Elliot Carver",
    88             "Elektra King"
     88            "Elektra King",
    8989            "Viktor Zokas",
    9090            "Gustav Graves",
  • code/trunk/src/orxonox/worldentities/pawns/SpaceShip.cc

    r7547 r7801  
    5757        this->engine_ = 0;
    5858
     59        this->boostPower_ = 10.0f;
     60        this->initialBoostPower_ = 10.0f;
     61        this->boostRate_ = 5.0;
     62        this->boostPowerRate_ = 1.0;
     63        this->boostCooldownDuration_ = 5.0;
     64        this->bBoostCooldown_ = false;
    5965
    6066        this->bInvertYAxis_ = false;
     
    8692        XMLPortParamVariable(SpaceShip, "auxilaryThrust", auxilaryThrust_, xmlelement, mode);
    8793        XMLPortParamVariable(SpaceShip, "rotationThrust", rotationThrust_, xmlelement, mode);
     94        XMLPortParamVariable(SpaceShip, "boostPower", initialBoostPower_, xmlelement, mode);
     95        XMLPortParamVariable(SpaceShip, "boostPowerRate", boostPowerRate_, xmlelement, mode);
     96        XMLPortParamVariable(SpaceShip, "boostRate", boostRate_, xmlelement, mode);
     97        XMLPortParamVariable(SpaceShip, "boostCooldownDuration", boostCooldownDuration_, xmlelement, mode);
    8898    }
    8999
     
    134144                this->localAngularAcceleration_.setValue(0, 0, 0);
    135145            }
    136         }
     146           
     147            if(!this->bBoostCooldown_ && this->boostPower_ < this->initialBoostPower_)
     148            {
     149                this->boostPower_ += this->boostPowerRate_*dt;
     150            }
     151            if(this->bBoost_)
     152            {
     153                this->boostPower_ -=this->boostRate_*dt;
     154                if(this->boostPower_ <= 0.0f)
     155                {
     156                    this->bBoost_ = false;
     157                    this->bBoostCooldown_ = true;
     158                    this->timer_.setTimer(this->boostCooldownDuration_, false, createExecutor(createFunctor(&SpaceShip::boostCooledDown, this)));
     159                }
     160            }
     161        }
     162    }
     163   
     164    void SpaceShip::boostCooledDown(void)
     165    {
     166        this->bBoostCooldown_ = false;
    137167    }
    138168
     
    175205        Pawn::rotateRoll(value);
    176206    }
     207   
     208    // TODO: something seems to call this function every tick, could probably handled a little more efficiently!
     209    void SpaceShip::setBoost(bool bBoost)
     210    {
     211        if(bBoost == this->bBoost_)
     212            return;
     213   
     214        if(bBoost)
     215            this->boost();
     216        else
     217        {
     218            this->bBoost_ = false;
     219        }
     220    }
    177221
    178222    void SpaceShip::fire()
     
    182226    void SpaceShip::boost()
    183227    {
    184         this->bBoost_ = true;
     228        if(!this->bBoostCooldown_)
     229            this->bBoost_ = true;
    185230    }
    186231
  • code/trunk/src/orxonox/worldentities/pawns/SpaceShip.h

    r7547 r7801  
    3434#include <string>
    3535#include <LinearMath/btVector3.h>
     36#include "tools/Timer.h"
    3637#include "util/Math.h"
    3738#include "Pawn.h"
     
    6970                { return this->steering_; }
    7071
    71             inline void setBoost(bool bBoost)
    72                 { this->bBoost_ = bBoost; }
     72            void setBoost(bool bBoost);
    7373            inline bool getBoost() const
    7474                { return this->bBoost_; }
     
    8989
    9090            bool bBoost_;
     91            bool bBoostCooldown_;
    9192            bool bPermanentBoost_;
     93            float boostPower_;
     94            float initialBoostPower_;
     95            float boostRate_;
     96            float boostPowerRate_;
     97            float boostCooldownDuration_;
    9298            Vector3 steering_;
    9399            float primaryThrust_;
     
    102108
    103109            void loadEngineTemplate();
     110           
     111            void boostCooledDown(void);
    104112
    105113            std::string enginetemplate_;
    106114            Engine* engine_;
     115            Timer timer_;
    107116    };
    108117}
Note: See TracChangeset for help on using the changeset viewer.