Index: code/branches/network3/src/network/Client.cc
===================================================================
--- code/branches/network3/src/network/Client.cc	(revision 1200)
+++ code/branches/network3/src/network/Client.cc	(revision 1232)
@@ -40,4 +40,5 @@
 
 #include "Client.h"
+#include "Synchronisable.h"
 #include "core/CoreIncludes.h"
 
@@ -47,6 +48,7 @@
   
   Client* Client::createSingleton(){
-    if(!_sClient)
+    if(!_sClient){
       _sClient = new Client();
+    }
     return _sClient;
   }
@@ -112,5 +114,12 @@
   */
   bool Client::establishConnection(){
+    Synchronisable::setClient(true);
     isConnected=client_connection.createConnection();
+    /*if(isConnected){
+      COUT(2) << "sending connectrequest" << std::endl;
+      client_connection.addPacket(pck_gen.generateConnectRequest());
+      client_connection.sendPackets();
+    }else
+      COUT(2) << "could not create connection" << std::endl;*/
     return isConnected;
   }
@@ -249,4 +258,11 @@
     COUT(0) << "Server: " << data->message << std::endl;
   }
+  
+  bool Client::processWelcome( welcome *w ){
+    COUT(4) << "processing welcome message" << std::endl;
+    clientID_ = w->clientID;
+    shipID_ = w->shipID;
+    
+  }
 
 }
Index: code/branches/network3/src/network/Client.h
===================================================================
--- code/branches/network3/src/network/Client.h	(revision 1200)
+++ code/branches/network3/src/network/Client.h	(revision 1232)
@@ -83,4 +83,7 @@
 
     bool sendPackets();
+    
+    int getShipID(){return shipID_;}
+    int getClientID(){return clientID_;}
 
     void tick(float time);
@@ -103,4 +106,7 @@
     void processClassid(classid *clid);
     void processChat( chat *data);
+    bool processWelcome( welcome *w );
+    int clientID_;     // this is the id the server gave to us
+    int shipID_;
   };
 
Index: code/branches/network3/src/network/ClientInformation.h
===================================================================
--- code/branches/network3/src/network/ClientInformation.h	(revision 1200)
+++ code/branches/network3/src/network/ClientInformation.h	(revision 1232)
@@ -67,10 +67,18 @@
     ClientInformation *insertBefore(ClientInformation *ins);
     ClientInformation *insertBack(ClientInformation *ins);
+    
+    // set functions
     void setID(int clientID);
     void setPeer(ENetPeer *peer);
     void setGamestateID(int id);
+    inline void setShipID(int id){ShipID_=id;}
+    
+    // get functions
+    inline int getShipID(){return ShipID_;}
     int getID();
+    int getGamestateID();
     ENetPeer *getPeer();
-    int getGamestateID();
+    
+    
     bool removeClient(int clientID);
     bool removeClient(ENetPeer *peer);
@@ -92,4 +100,5 @@
     int clientID_;
     int gamestateID_;
+    int ShipID_;   // this is the unique objectID
     bool synched_;
   };
Index: code/branches/network3/src/network/ConnectionManager.cc
===================================================================
--- code/branches/network3/src/network/ConnectionManager.cc	(revision 1200)
+++ code/branches/network3/src/network/ConnectionManager.cc	(revision 1232)
@@ -44,6 +44,10 @@
 
 #include "core/CoreIncludes.h"
+#include "core/BaseObject.h"
+#include "util/Math.h"
+#include "objects/SpaceShip.h"
 #include "ClientInformation.h"
 #include "ConnectionManager.h"
+#include "Synchronisable.h"
 
 namespace std
@@ -179,4 +183,7 @@
         case ENET_EVENT_TYPE_CONNECT:
           addClient(&event);
+          //this is a workaround to ensure thread safety
+          if(!addFakeConnectRequest(&event))
+            COUT(3) << "Problem pushing fakeconnectRequest to queue" << std::endl;
           COUT(5) << "Con.Man: connection event has occured" << std::endl;
           break;
@@ -237,8 +244,4 @@
   }
 
-  //bool ConnectionManager::clientDisconnect(ENetPeer *peer) {
-  //  return clientDisconnect(*peer);
-  //}
-
   bool ConnectionManager::clientDisconnect(ENetPeer *peer) {
     COUT(4) << "removing client from list" << std::endl;
@@ -260,6 +263,4 @@
     temp->setPeer(event->peer);
     COUT(4) << "Con.Man: added client id: " << temp->getID() << std::endl;
-    syncClassid(temp->getID());
-    temp->setSynched(true);
     return true;
   }
@@ -298,36 +299,88 @@
   }
 
-
-
-  void ConnectionManager::addClientsObjectID( int clientID, int objectID ) {
-    COUT(4) << "ship of client: " << clientID << ": " << objectID << " mapped" << std::endl;
-    clientsShip.insert( std::make_pair( clientID, objectID ) );
-  }
+  bool ConnectionManager::createClient(int clientID){
+    ClientInformation *temp = head_->findClient(clientID);
+    COUT(4) << "Con.Man: creating client id: " << temp->getID() << std::endl;
+    syncClassid(temp->getID());
+    COUT(4) << "creating spaceship for clientid: " << temp->getID() << std::endl;
+    // TODO: this is only a hack, untill we have a possibility to define default player-join actions
+    createShip(temp);
+    COUT(4) << "created spaceship" << std::endl;
+    temp->setSynched(true);
+    COUT(4) << "sending welcome" << std::endl;
+    sendWelcome(temp->getID(), temp->getShipID(), true);
+    return true;
+  }
+  
+  bool ConnectionManager::createShip(ClientInformation *client){
+    orxonox::Identifier* id = ID("SpaceShip");
+    if(!id){
+      COUT(4) << "We could not create the SpaceShip for client: " << client->getID() << std::endl;
+      return false;
+    }
+    orxonox::SpaceShip *no = dynamic_cast<orxonox::SpaceShip *>(id->fabricate());
+    no->setPosition(orxonox::Vector3(0,80,0));
+    no->setScale(10);
+    no->setYawPitchRoll(orxonox::Degree(-90),orxonox::Degree(-90),orxonox::Degree(0));
+    no->setMesh("assf3.mesh");
+    no->setMaxSpeed(500);
+    no->setMaxSideAndBackSpeed(50);
+    no->setMaxRotation(1.0);
+    no->setTransAcc(200);
+    no->setRotAcc(3.0);
+    no->setTransDamp(75);
+    no->setRotDamp(1.0);
+    no->setCamera("cam_"+client->getID());
+    no->create();
+    
+    client->setShipID(no->objectID);
+    return true;
+  }
+  
+  bool ConnectionManager::sendWelcome(int clientID, int shipID, bool allowed){
+    addPacket(packet_gen.generateWelcome(clientID, shipID, allowed),clientID);
+    sendPackets();
+  }
+  
+  bool ConnectionManager::addFakeConnectRequest(ENetEvent *ev){
+    ENetEvent event;
+    event.peer=ev->peer;
+    event.packet = packet_gen.generateConnectRequest();
+    return buffer.push(&event);
+  }
+  
+  
+//   int ConnectionManager::getNumberOfClients() {
+//     
+//     return clientsShip.size();
+//   }
+  
+  /*void ConnectionManager::addClientsObjectID( int clientID, int objectID ) {
+  COUT(4) << "ship of client: " << clientID << ": " << objectID << " mapped" << std::endl;
+  clientsShip.insert( std::make_pair( clientID, objectID ) );
+}
 
   int ConnectionManager::getClientsShipID( int clientID ) {
-    return clientsShip[clientID];
-  }
+  return clientsShip[clientID];
+}
 
   int ConnectionManager::getObjectsClientID( int objectID ) {
-    std::map<int, int>::iterator iter;
-    for( iter = clientsShip.begin(); iter != clientsShip.end(); iter++ ) {
-      if( iter->second == objectID ) return iter->first;
-    }
-    return -99;
-  }
+  std::map<int, int>::iterator iter;
+  for( iter = clientsShip.begin(); iter != clientsShip.end(); iter++ ) {
+  if( iter->second == objectID ) return iter->first;
+}
+  return -99;
+}
 
   void ConnectionManager::deleteClientIDReg( int clientID ) {
-    clientsShip.erase( clientID );
-  }
+  clientsShip.erase( clientID );
+}
 
   void ConnectionManager::deleteObjectIDReg( int objectID ) {
-    std::map<int, int>::iterator iter = clientsShip.begin();
-    for( iter = clientsShip.begin(); iter != clientsShip.end(); iter++ ) {
-      if( iter->second == objectID ) break;
-    }
-    clientsShip.erase( iter->first );
-  }
-  int ConnectionManager::getNumberOfClients() {
-    return clientsShip.size();
-  }
-}
+  std::map<int, int>::iterator iter = clientsShip.begin();
+  for( iter = clientsShip.begin(); iter != clientsShip.end(); iter++ ) {
+  if( iter->second == objectID ) break;
+}
+  clientsShip.erase( iter->first );
+}*/
+}
Index: code/branches/network3/src/network/ConnectionManager.h
===================================================================
--- code/branches/network3/src/network/ConnectionManager.h	(revision 1200)
+++ code/branches/network3/src/network/ConnectionManager.h	(revision 1232)
@@ -71,4 +71,5 @@
   class ConnectionManager{
   public:
+    ConnectionManager();
     ConnectionManager(ClientInformation *head);
     ConnectionManager(int port, const char *address, ClientInformation *head);
@@ -84,29 +85,8 @@
     bool sendPackets(ENetEvent *event);
     bool sendPackets();
+    bool createClient(int clientID);
 
-    //##### for testing purpose only #####
-    ConnectionManager();
-    std::map<int, int> testGetClientsShip() { 
-      return clientsShip; 
-    }
-    void testAddClientsShipID( int clientID, int objectID ) {
-      addClientsObjectID( clientID, objectID );
-    }
-    int testGetClientsShipID( int clientID ) { 
-      return getClientsShipID( clientID ); 
-    }
-    int testGetObjectsClientID( int objectID ) {
-       return getObjectsClientID( objectID );
-    }
-    void testDeleteClientsIDReg( int clientID ) { 
-      deleteClientIDReg( clientID );
-    }
-    void testDeleteObjectIDReg( int objectID ) {
-      deleteObjectIDReg( objectID );
-    }
-    //##### for testing purpose only #####
   private:
     bool clientDisconnect(ENetPeer *peer);
-    //bool clientDisconnect(ENetPeer peer);
     bool processData(ENetEvent *event);
     bool addClient(ENetEvent *event);
@@ -117,4 +97,7 @@
     void syncClassid(int clientID);
     ENetPeer *getClientPeer(int clientID);
+    bool createShip(ClientInformation *client);
+    bool sendWelcome(int clientID, int shipID, bool allowed);
+    bool addFakeConnectRequest(ENetEvent *ev);
     PacketBuffer buffer;
     PacketGenerator packet_gen;
@@ -126,12 +109,13 @@
     ClientInformation *head_;
 
+    
+//     int getNumberOfClients();
     //functions to map what object every clients uses
-    std::map<int, int> clientsShip;
+    /*std::map<int, int> clientsShip;
     void addClientsObjectID( int clientID, int objectID );
     int getClientsShipID( int clientID );
     int getObjectsClientID( int objectID );
     void deleteClientIDReg( int clientID );
-    void deleteObjectIDReg( int objectID );
-    int getNumberOfClients();
+    void deleteObjectIDReg( int objectID );*/
   };
 
Index: code/branches/network3/src/network/GameStateClient.cc
===================================================================
--- code/branches/network3/src/network/GameStateClient.cc	(revision 1200)
+++ code/branches/network3/src/network/GameStateClient.cc	(revision 1232)
@@ -86,4 +86,10 @@
     return false;
   }
+  
+  GameStateCompressed *GameStateClient::popPartialGameState(){
+    GameState *gs = getPartialSnapshot();
+    return compress_(gs);
+  }
+  
 
   /**
@@ -137,8 +143,7 @@
           }
           Synchronisable *no = dynamic_cast<Synchronisable *>(id->fabricate());
-          COUT(4) << "loadsnapshort: classid: " << sync.classID << " objectID: " << sync.objectID << " length: " << sync.length << std::endl;
+          COUT(4) << "loadsnapshot: classid: " << sync.classID << " objectID: " << sync.objectID << " length: " << sync.length << std::endl;
           no->objectID=sync.objectID;
           no->classID=sync.classID;
-          it=orxonox::ObjectList<Synchronisable>::end();
           // update data and create object/entity...
           if( !no->updateData(sync) )
@@ -146,4 +151,5 @@
           if( !no->create() )
             COUT(1) << "We couldn't manifest (create() ) the object: " << sync.objectID << std::endl;
+          it=orxonox::ObjectList<Synchronisable>::end();
         }
       } else {
@@ -159,5 +165,68 @@
   }
 
+  GameState *GameStateClient::getPartialSnapshot(){
+    //std::cout << "begin getSnapshot" << std::endl;
+    //the size of the gamestate
+    int totalsize=0;
+    int memsize=0;
+    //the size of one specific synchronisable
+    int tempsize=0;
+    // get the start of the Synchronisable list
+    orxonox::Iterator<Synchronisable> it;
+    // struct for return value of Synchronisable::getData()
+    syncData sync;
+
+    GameState *retval=new GameState; //return value
+    retval->id=reference->id;
+    retval->diffed=false;
+    retval->complete=false;
+    COUT(4) << "G.ST.Client: producing partial gamestate with id: " << retval->id << std::endl;
+    // offset of memory functions
+    int offset=0, size=0;
+    // get total size of gamestate
+    for(it = orxonox::ObjectList<Synchronisable>::start(); it; ++it){
+      if(!it->getBacksync())
+        continue;
+      size+=it->getSize(); // size of the actual data of the synchronisable
+      size+=3*sizeof(int); // size of datasize, classID and objectID
+    }
+    //retval->data = (unsigned char*)malloc(size);
+    retval->data = new unsigned char[size];
+    if(!retval->data){
+      COUT(2) << "GameStateClient: could not allocate memory" << std::endl;
+      return NULL;
+    }
+    memsize=size;
+    // go through all Synchronisables
+    for(it = orxonox::ObjectList<Synchronisable>::start(); it; ++it){
+      if(!it->getBacksync())
+        continue;
+      //get size of the synchronisable
+      tempsize=it->getSize();
+      // add place for data and 3 ints (length,classid,objectid)
+      totalsize+=tempsize+3*sizeof(int);
+      // allocate+tempsize additional space
+      if(totalsize > size){
+        COUT(3) << "G.St.Cl: need additional memory" << std::endl;
+      }
+
+      // run Synchronisable::getData with offset and additional place for 3 ints in between (for ids and length)
+      sync=it->getData((retval->data)+offset+3*sizeof(int));
+      memcpy(retval->data+offset, (void *)&(sync.length), sizeof(int));
+      memcpy(retval->data+offset+sizeof(int), (void *)&(sync.objectID), sizeof(int));
+      memcpy(retval->data+offset+2*sizeof(int), (void *)&(sync.classID), sizeof(int));
+      // increase data pointer
+      offset+=tempsize+3*sizeof(int);
+    }
+    retval->size=totalsize;
+    COUT(5) << "G.ST.Cl: Gamestate size: " << totalsize << std::endl;
+    COUT(5) << "G.ST.Cl: 'estimated' Gamestate size: " << size << std::endl;
+    return retval;
+  }
+  
+  
   GameState *GameStateClient::undiff(GameState *old, GameState *diff) {
+    if(!old || !diff)
+      return NULL;
     unsigned char *ap = old->data, *bp = diff->data;
     int of=0; // pointers offset
@@ -195,17 +264,44 @@
     r->diffed = false;
     r->data = dp;
+    r->complete = true;
     return r;
   }
 
-  //##### ADDED FOR TESTING PURPOSE #####
-  GameState* GameStateClient::testDecompress( GameStateCompressed* gc ) {
-    return decompress( gc );
-  }
-  
-  GameState* GameStateClient::testUndiff( GameState* g_old, GameState* g_diffed ) {
-    return undiff( g_old, g_diffed );
-  }
-  //##### ADDED FOR TESTING PURPOSE #####
-
+
+
+  GameStateCompressed *GameStateClient::compress_(GameState *a) {
+    if(!a)
+      return NULL;
+    int size = a->size;
+
+    uLongf buffer = (uLongf)((a->size + 12)*1.01)+1;
+    unsigned char *dest = new unsigned char[buffer];
+    int retval;
+    retval = compress( dest, &buffer, a->data, (uLong)size );
+
+    switch ( retval ) {
+      case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break;
+      case Z_MEM_ERROR: COUT(1) << "G.St.Man: compress: not enough memory available in gamestate.compress" << std::endl; 
+      return NULL;
+      case Z_BUF_ERROR: COUT(2) << "G.St.Man: compress: not enough memory available in the buffer in gamestate.compress" << std::endl;
+      return NULL;
+      case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl;
+      return NULL;
+    }
+
+    GameStateCompressed *compressedGamestate = new GameStateCompressed;
+    compressedGamestate->compsize = buffer;
+    compressedGamestate->normsize = size;
+    compressedGamestate->id = a->id;
+    compressedGamestate->data = dest;
+    compressedGamestate->diffed = a->diffed;
+    compressedGamestate->complete = a->complete;
+    compressedGamestate->base_id = a->base_id;
+    delete[] a->data;
+    delete a;
+    return compressedGamestate;
+  }
+  
+  
   GameState *GameStateClient::decompress(GameStateCompressed *a) {
     //COUT(4) << "GameStateClient: uncompressing gamestate. id: " << a->id << ", baseid: " << a->base_id << ", normsize: " << a->normsize << ", compsize: " << a->compsize << std::endl;
@@ -238,4 +334,5 @@
     gamestate->base_id = a->base_id;
     gamestate->diffed = a->diffed;
+    gamestate->complete = a->complete;
 
     delete[] a->data; //delete compressed data
@@ -286,3 +383,16 @@
   }
   
+  
+    //##### ADDED FOR TESTING PURPOSE #####
+  GameState* GameStateClient::testDecompress( GameStateCompressed* gc ) {
+    return decompress( gc );
+  }
+  
+  GameState* GameStateClient::testUndiff( GameState* g_old, GameState* g_diffed ) {
+    return undiff( g_old, g_diffed );
+  }
+  //##### ADDED FOR TESTING PURPOSE #####
+  
+  
 }
+
Index: code/branches/network3/src/network/GameStateClient.h
===================================================================
--- code/branches/network3/src/network/GameStateClient.h	(revision 1200)
+++ code/branches/network3/src/network/GameStateClient.h	(revision 1232)
@@ -42,8 +42,9 @@
 
 #include <map>
-
+// 
 #include "NetworkPrereqs.h"
 #include "core/CorePrereqs.h"
 #include "PacketTypes.h"
+
 
 namespace network
@@ -54,13 +55,13 @@
     GameStateClient();
     ~GameStateClient();
-    //#### ADDED FOR TESTING PURPOSE ####
-    GameState* testDecompress( GameStateCompressed* gc );
-    GameState* testUndiff( GameState* g_old, GameState* g_diffed );
-    //#### END TESTING PURPOSE ####
+    
     bool pushGameState(GameStateCompressed *compstate);
+    GameStateCompressed *popPartialGameState();
   private:
     bool loadSnapshot(GameState *state);
+    GameState *getPartialSnapshot();
     void cleanup();
     GameState *undiff(GameState *old, GameState *diff);
+    GameStateCompressed *compress_(GameState *a);
     GameState *decompress(GameStateCompressed *a);
     GameState *decode(GameState *old, GameStateCompressed *diff);
@@ -72,4 +73,13 @@
     int           last_diff_;
     std::map<int, GameState *> gameStateMap;
+    
+    
+    
+    
+  public:
+    //#### ADDED FOR TESTING PURPOSE ####
+    GameState* testDecompress( GameStateCompressed* gc );
+    GameState* testUndiff( GameState* g_old, GameState* g_diffed );
+    //#### END TESTING PURPOSE ####
   };
 
Index: code/branches/network3/src/network/GameStateManager.cc
===================================================================
--- code/branches/network3/src/network/GameStateManager.cc	(revision 1200)
+++ code/branches/network3/src/network/GameStateManager.cc	(revision 1232)
@@ -46,4 +46,5 @@
 
 #include "core/CoreIncludes.h"
+#include "core/BaseObject.h"
 #include "ClientInformation.h"
 #include "Synchronisable.h"
@@ -122,4 +123,10 @@
     }
   }
+  
+  bool GameStateManager::pushGameState( GameStateCompressed *gs, int clientID ){
+    GameState *ugs = decompress(gs);
+    return loadPartialSnapshot(ugs, clientID);
+    
+  }
 
   /**
@@ -188,4 +195,5 @@
     //#### bugfix
     retval->diffed = false;
+    retval->complete = true;
     //std::cout << "end snapShot" << std::endl;
     COUT(5) << "G.ST.Man: Gamestate size: " << totalsize << std::endl;
@@ -194,4 +202,60 @@
   }
 
+  bool GameStateManager::loadPartialSnapshot(GameState *state, int clientID){
+    unsigned char *data=state->data;
+    COUT(4) << "loadSnapshot: loading gs: " << state->id << std::endl;
+    // get the start of the Synchronisable list
+    orxonox::Iterator<Synchronisable> it=orxonox::ObjectList<Synchronisable>::start();
+    syncData sync;
+    // loop as long as we have some data ;)
+    while(data < state->data+state->size){
+      // prepare the syncData struct
+      sync.length = *(int *)data;
+      data+=sizeof(int);
+      sync.objectID = *(int*)data;
+      data+=sizeof(int);
+      sync.classID = *(int*)data;
+      data+=sizeof(int);
+      sync.data = data;
+      data+=sync.length;
+
+      while(it && it->objectID!=sync.objectID)
+        ++it;
+
+
+      if(!it){
+        // the object does not exist yet
+        //COUT(4) << "loadSnapshot:\tclassid: " << sync.classID << ", name: " << ID((unsigned int) sync.classID)->getName() << std::endl;
+        orxonox::Identifier* id = ID((unsigned int)sync.classID);
+        if(!id){
+          COUT(4) << "We could not identify a new object; classid: " << sync.classID << std::endl;
+          continue;
+        }
+        Synchronisable *no = dynamic_cast<Synchronisable *>(id->fabricate());
+        COUT(4) << "loadpartialsnapshot (generating new object): classid: " << sync.classID << " objectID: " << sync.objectID << " length: " << sync.length << std::endl;
+        no->objectID=sync.objectID;
+        no->classID=sync.classID;
+        it=orxonox::ObjectList<Synchronisable>::end();
+        // update data and create object/entity...
+        if( !no->updateData(sync) )
+          COUT(1) << "We couldn't update the object: " << sync.objectID << std::endl;
+        if( !no->create() )
+          COUT(1) << "We couldn't manifest (create() ) the object: " << sync.objectID << std::endl;
+      }else{
+        // we have our object
+        if(checkAccess(clientID, sync.objectID)){
+          if(! it->updateData(sync))
+            COUT(1) << "We couldn't update objectID: " \
+              << sync.objectID << "; classID: " << sync.classID << std::endl;
+        }else
+          COUT(4) << "loadPartialSnapshot: no access to change objectID: " << sync.objectID << std::endl;
+      }
+      ++it;
+    }
+
+    return true;
+  }
+  
+  
   //##### ADDED FOR TESTING PURPOSE #####
   GameStateCompressed* GameStateManager::testCompress( GameState* g ) {
@@ -269,4 +333,5 @@
     r->base_id = a->id;
     r->data = dp;
+    r->complete = true;
     return r;
   }
@@ -307,8 +372,48 @@
     compressedGamestate->data = dest;
     compressedGamestate->diffed = a->diffed;
+    compressedGamestate->complete = a->complete;
     compressedGamestate->base_id = a->base_id;
     //COUT(5) << "G.St.Man: saved compressed data in GameStateCompressed:" << std::endl;
     return compressedGamestate;
   }
+  
+  GameState *GameStateManager::decompress(GameStateCompressed *a) {
+    //COUT(4) << "GameStateClient: uncompressing gamestate. id: " << a->id << ", baseid: " << a->base_id << ", normsize: " << a->normsize << ", compsize: " << a->compsize << std::endl;
+    int normsize = a->normsize;
+    int compsize = a->compsize;
+    int bufsize;
+    if(normsize < compsize)
+      bufsize = compsize;
+    else
+      bufsize = normsize;
+//     unsigned char* dest = (unsigned char*)malloc( bufsize );
+    unsigned char *dest = new unsigned char[bufsize];
+    int retval;
+    uLongf length=normsize;
+    //std::cout << "gamestateclient" << std::endl;
+    //std::cout << "normsize " << a.normsize << " compsize " << a.compsize << " " << bufsize << std::endl;
+    retval = uncompress( dest, &length, a->data, (uLong)compsize );
+    //std::cout << "length " << length << std::endl;
+    switch ( retval ) {
+      case Z_OK: COUT(4) << "successfully decompressed" << std::endl; break;
+      case Z_MEM_ERROR: COUT(1) << "not enough memory available" << std::endl; return NULL;
+      case Z_BUF_ERROR: COUT(2) << "not enough memory available in the buffer" << std::endl; return NULL;
+      case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return NULL;
+    }
+
+    GameState *gamestate = new GameState;
+    gamestate->id = a->id;
+    gamestate->size = normsize;
+    gamestate->data = dest;
+    gamestate->base_id = a->base_id;
+    gamestate->diffed = a->diffed;
+    gamestate->complete = a->complete;
+
+    delete[] a->data; //delete compressed data
+    delete a; //we do not need the old (struct) gamestate anymore
+
+    return gamestate;
+  }
+  
 
   void GameStateManager::ackGameState(int clientID, int gamestateID) {
@@ -336,4 +441,9 @@
     COUT(4) << std::endl;
   }
+  
+  bool GameStateManager::checkAccess(int clientID, int objectID){
+    // currently we only check, wheter the object is the clients spaceship
+    return head_->findClient(objectID)->getShipID()==objectID;
+  }
 
 }
Index: code/branches/network3/src/network/GameStateManager.h
===================================================================
--- code/branches/network3/src/network/GameStateManager.h	(revision 1200)
+++ code/branches/network3/src/network/GameStateManager.h	(revision 1232)
@@ -71,19 +71,20 @@
     GameStateManager(ClientInformation *head);
     ~GameStateManager();
-    //#### ADDED FOR TESTING PURPOSE ####
-    GameStateCompressed* testCompress( GameState* g );
-    GameState* testDiff( GameState* a, GameState* b );
-    //#### END TESTING PURPOSE ####
+    
     void update();
     GameStateCompressed *popGameState(int clientID);
+    bool pushGameState(GameStateCompressed *gs, int clientID);
     void ackGameState(int clientID, int gamestateID);
   private:
     void cleanup(); // "garbage handler"
     GameState *getSnapshot();
+    bool loadPartialSnapshot(GameState *state, int clientID);
     GameStateCompressed *encode(GameState *a, GameState *b);
     GameStateCompressed *encode(GameState *a);
     GameState *diff(GameState *a, GameState *b);
     GameStateCompressed *compress_(GameState *a);
+    GameState *decompress(GameStateCompressed *a);
     bool printGameStates();
+    bool checkAccess(int clientID, int objectID);
 
     std::map<int, GameState*> gameStateMap; //map gsID to gamestate*
@@ -92,4 +93,13 @@
     ClientInformation *head_;
     int id_;
+    
+    
+    
+    
+  public:
+    //#### ADDED FOR TESTING PURPOSE ####
+    GameStateCompressed* testCompress( GameState* g );
+    GameState* testDiff( GameState* a, GameState* b );
+  //#### END TESTING PURPOSE ####
   };
 
Index: code/branches/network3/src/network/NetworkPrereqs.h
===================================================================
--- code/branches/network3/src/network/NetworkPrereqs.h	(revision 1200)
+++ code/branches/network3/src/network/NetworkPrereqs.h	(revision 1232)
@@ -78,4 +78,6 @@
   struct chat;
   struct classid;
+  struct welcome;
+  struct connectRequest;
   struct ClientList;
   struct GameState;
Index: code/branches/network3/src/network/PacketDecoder.cc
===================================================================
--- code/branches/network3/src/network/PacketDecoder.cc	(revision 1200)
+++ code/branches/network3/src/network/PacketDecoder.cc	(revision 1232)
@@ -53,6 +53,5 @@
   bool PacketDecoder::elaborate( ENetPacket* packet, int clientId )
   {
-    int client = clientId;
-    COUT(5) << "PacketDecoder: clientId: " << client << std::endl; //control cout, not important, just debugging info
+    COUT(5) << "PacketDecoder: clientId: " << clientId << std::endl; //control cout, not important, just debugging info
     int id = (int)*packet->data; //the first 4 bytes are always the enet packet id
     COUT(5) << "PacketDecoder: packet id: " << id << std::endl;
@@ -64,28 +63,28 @@
     }
     switch( id ) {
-  case ACK:
-    acknowledgement( packet, clientId );
-    return true;
-    break;
-  case MOUSE:
-    mousem( packet, clientId );
-    return true;
-    break;
-  case KEYBOARD:
-    keystrike( packet, clientId );
-    return true;
-    break;
-  case CHAT:
-    chatMessage( packet, clientId );
-    return true;
-    break;
-  case GAMESTATE:
-    gstate( packet );
-    return true;
-    break;
-  case CLASSID:
-    clid(packet);
-    return true;
-    break;
+    case ACK:
+      acknowledgement( packet, clientId );
+      return true;
+    case COMMAND:
+      return command( packet, clientId );
+    case MOUSE:
+      mousem( packet, clientId );
+      return true;
+    case KEYBOARD:
+      keystrike( packet, clientId );
+      return true;
+    case CHAT:
+      chatMessage( packet, clientId );
+      return true;
+    case GAMESTATE:
+      gstate( packet );
+      return true;
+    case CLASSID:
+      clid(packet);
+      return true;
+    case WELCOME:
+      return decodeWelcome( packet, clientId );
+    case CONNECT:
+      return decodeConnectRequest( packet, clientId );
     }
     return false;
@@ -105,4 +104,11 @@
     //clean memory
     enet_packet_destroy( packet );
+  }
+  
+  bool PacketDecoder::command( ENetPacket* packet, int clientId ){
+    int length = *(int*)((unsigned char *)packet->data+sizeof(int));
+    void *data = (void *)new unsigned char[length];
+    memcpy(data, (void *)(packet->data+2*sizeof(int)), length);
+    return true;
   }
 
@@ -171,4 +177,5 @@
     //since the packetgenerator was changed, due to a new parameter, change this function too
     memcpy( (void*)&(currentState->diffed), (const void*)(packet->data+5*sizeof(int)), sizeof(bool));
+    memcpy( (void*)&(currentState->complete), (const void*)(packet->data+5*sizeof(int)+sizeof(bool)), sizeof(bool));
     //since data is not allocated, because it's just a pointer, allocate it with size of gamestatedatastream
     if(currentState->compsize==0)
@@ -178,5 +185,5 @@
       COUT(2) << "PacketDecoder: Gamestatepacket-decoder: memory leak" << std::endl;
     //copy the GameStateCompressed data
-    memcpy( (void*)(currentState->data), (const void*)(packet->data+5*sizeof( int ) + sizeof(bool)), currentState->compsize );
+    memcpy( (void*)(currentState->data), (const void*)(packet->data+5*sizeof( int ) + 2*sizeof(bool)), currentState->compsize );
 
     //clean memory
@@ -198,4 +205,22 @@
     processClassid(cid);
   }
+  
+  
+  bool PacketDecoder::decodeWelcome( ENetPacket* packet, int clientID ){
+    welcome *w = new welcome;
+    w->allowed = ((welcome *)(packet->data))->allowed;
+    w->shipID = ((welcome *)(packet->data))->shipID;
+    w->clientID = ((welcome *)(packet->data))->clientID;
+    w->id = ((welcome *)(packet->data))->id;
+    enet_packet_destroy( packet );
+    return processWelcome(w);
+  }
+  
+  bool PacketDecoder::decodeConnectRequest( ENetPacket *packet, int clientID ){
+    connectRequest *con = new connectRequest;
+    con->id = ((connectRequest *)(packet->data))->id;
+    enet_packet_destroy( packet );
+    return processConnectRequest(con, clientID );
+  }
 
 
@@ -224,5 +249,13 @@
     return;
   }
-
+  
+  bool PacketDecoder::processWelcome( welcome *w ){
+    return true;
+  }
+  
+  bool PacketDecoder::processConnectRequest( connectRequest *con, int clientID ){
+    COUT(3) << "packetdecoder: processing connectRequest" << std::endl;
+    return true;
+  }
 
   //these are some print functions for test stuff
Index: code/branches/network3/src/network/PacketGenerator.cc
===================================================================
--- code/branches/network3/src/network/PacketGenerator.cc	(revision 1200)
+++ code/branches/network3/src/network/PacketGenerator.cc	(revision 1232)
@@ -61,4 +61,16 @@
     return packet;
   }
+  
+  ENetPacket* command( int dataLength, void *data, int reliable = ENET_PACKET_FLAG_RELIABLE )
+  {
+    void *stream = new char[dataLength + 2*sizeof(int)];
+    if(!stream)
+      return NULL;
+    packet_id a = COMMAND;
+    memcpy(stream, (void*)&a, sizeof(int));
+    memcpy((unsigned char *)stream+sizeof(int), (void*)&dataLength, sizeof(int));
+    memcpy((unsigned char *)stream+2*sizeof(int), data, dataLength);
+    return enet_packet_create(stream, dataLength+2*sizeof(int), reliable);
+  }
 
   /*### mouseupdates */
@@ -108,7 +120,8 @@
     //std::cout << "states->compsize " << states->compsize << std::endl;
     int gid = GAMESTATE; //first assign the correct enet id
-    int totalLen = 5*sizeof( int ) + sizeof(bool) + states->compsize; //calculate the total size of the datastream memory
+    int totalLen = 5*sizeof( int ) + 2*sizeof(bool) + states->compsize; //calculate the total size of the datastream memory
     //std::cout << "totalLen " << totalLen << std::endl;
-    unsigned char *data = (unsigned char*)malloc( totalLen ); //allocate the memory for datastream
+    //unsigned char *data = (unsigned char*)malloc( totalLen ); //allocate the memory for datastream
+    unsigned char *data = new unsigned char[totalLen];
     memcpy( (void*)(data), (const void*)&gid, sizeof( int ) ); //this is the enet id
     memcpy( (void*)(data+sizeof(int)), (const void*)&(states->id), sizeof(int) ); //the GameStateCompressed id
@@ -118,5 +131,6 @@
     memcpy( (void*)(data+5*sizeof(int)), (const void*)&(states->diffed), sizeof(bool));
     //place the GameStateCompressed data at the end of the enet datastream
-    memcpy( (void*)(data+5*sizeof( int ) + sizeof(bool)), (const void*)states->data, states->compsize );
+    memcpy( (void*)(data+5*sizeof( int ) + sizeof(bool)), (const void*)&(states->complete), sizeof(bool) );
+    memcpy( (void*)(data+5*sizeof( int ) + 2*sizeof(bool)), (const void*)states->data, states->compsize );
     //create an enet packet with the generated bytestream
     COUT(4) << "PacketGenerator generating totalLen " << totalLen << std::endl;
@@ -128,5 +142,6 @@
   ENetPacket* PacketGenerator::clid( int classid, std::string classname, int reliable )
   {
-    unsigned char* data = (unsigned char *)malloc(3*sizeof(int)+classname.length()+1);
+    //unsigned char* data = (unsigned char *)malloc(3*sizeof(int)+classname.length()+1);
+    unsigned char *data = new unsigned char[3*sizeof(int)+classname.length()+1];
     std::cout << "PacketGenerator: classid: " << classid << ", name: " << classname << std::endl;
     *(int *)data = CLASSID;
@@ -137,4 +152,20 @@
     return packet;
   }
+  
+  ENetPacket* PacketGenerator::generateWelcome( int clientID,int shipID, bool allowed , int reliable ){
+    welcome *wc = new welcome;
+    wc->id = WELCOME;
+    wc->clientID = clientID;
+    wc->shipID = shipID;
+    wc->allowed = true;
+    ENetPacket *packet = enet_packet_create( wc, sizeof(welcome), reliable);
+    return packet;
+  }
+  
+  ENetPacket* PacketGenerator::generateConnectRequest( int reliable ){
+    connectRequest *con = new connectRequest;
+    con->id=CONNECT;
+    return enet_packet_create( con, sizeof(connectRequest), reliable);
+  }
 
 }
Index: code/branches/network3/src/network/PacketManager.h
===================================================================
--- code/branches/network3/src/network/PacketManager.h	(revision 1200)
+++ code/branches/network3/src/network/PacketManager.h	(revision 1232)
@@ -54,4 +54,5 @@
     //call one of this functions out of an instance of PacketGenerator to create a packet
     ENetPacket* acknowledgement( int state, int reliable = ENET_PACKET_FLAG_RELIABLE );
+    ENetPacket* command( int dataLength, void *data, int reliable = ENET_PACKET_FLAG_RELIABLE );
     ENetPacket* mousem( double x, double y, int reliable = ENET_PACKET_FLAG_RELIABLE );
     ENetPacket* keystrike( char press, int reliable = ENET_PACKET_FLAG_RELIABLE );
@@ -59,4 +60,6 @@
     ENetPacket* gstate( GameStateCompressed *states, int reliable = ENET_PACKET_FLAG_RELIABLE );
     ENetPacket* clid( int classid, std::string classname, int reliable = ENET_PACKET_FLAG_RELIABLE );
+    ENetPacket* generateWelcome( int clientID,int shipID, bool allowed, int reliable = ENET_PACKET_FLAG_RELIABLE );
+    ENetPacket* generateConnectRequest( int reliable = ENET_PACKET_FLAG_RELIABLE );
   private:
   };
@@ -85,4 +88,5 @@
 
     void acknowledgement( ENetPacket* packet, int clientId = CLIENTID_CLIENT );
+    bool command( ENetPacket* packet, int clientId );
     void mousem( ENetPacket* packet, int clientId = CLIENTID_CLIENT );
     void keystrike( ENetPacket* packet, int clientId = CLIENTID_CLIENT );
@@ -90,4 +94,6 @@
     void gstate( ENetPacket* packet );
     void clid( ENetPacket *packet);
+    bool decodeWelcome( ENetPacket* packet, int clientID = CLIENTID_CLIENT );
+    bool decodeConnectRequest( ENetPacket *packet, int clientID = CLIENTID_CLIENT );
 
     //process data
@@ -96,4 +102,6 @@
     virtual void processAck( ack *data, int clientID);
     virtual void processClassid( classid *cid);
+    virtual bool processWelcome( welcome *w );
+    virtual bool processConnectRequest( connectRequest *con, int clientID );
     //virtual void processAck( ack *data);
 
Index: code/branches/network3/src/network/PacketTypes.h
===================================================================
--- code/branches/network3/src/network/PacketTypes.h	(revision 1200)
+++ code/branches/network3/src/network/PacketTypes.h	(revision 1232)
@@ -49,8 +49,11 @@
     ACK,
     MOUSE,
+    COMMAND,
     KEYBOARD,
     CHAT,
     GAMESTATE ,
-    CLASSID
+    CLASSID,
+    WELCOME,
+    CONNECT,
   };
 
@@ -65,6 +68,7 @@
     int size;                       //!< total size of data
     // new ---- change functions
-    int base_id;                  // if gamestate is diffed this is the id of the old gamestate (base)
+    int base_id;                    // if gamestate is diffed this is the id of the old gamestate (base)
     bool diffed;
+    bool complete;                  // this determines, wheter all objects are in this gamestate (server) or only few objects (client)
     unsigned char *data;            //!< pointer to data
   };
@@ -83,4 +87,5 @@
     int base_id;                  // if gamestate is diffed this is the id of the old gamestate (base)
     bool diffed;
+    bool complete;                  // this determines, wheter all objects are in this gamestate (server) or only few objects (client)
     unsigned char *data;            //!< gamestate data
   };
@@ -116,4 +121,14 @@
   };
 
+  struct welcome {
+    int id;
+    int clientID;
+    int shipID;
+    bool allowed;
+  };
+  
+  struct connectRequest{
+    int id;
+  };
 }
 
Index: code/branches/network3/src/network/Server.cc
===================================================================
--- code/branches/network3/src/network/Server.cc	(revision 1200)
+++ code/branches/network3/src/network/Server.cc	(revision 1232)
@@ -223,4 +223,10 @@
     gamestates->ackGameState(clientID, data->a);
   }
+  
+  bool Server::processConnectRequest( connectRequest *con, int clientID ){
+    COUT(4) << "processing connectRequest " << std::endl;
+    //connection->addPacket(packet_gen.gstate(gamestates->popGameState(clientID)) , clientID);
+    connection->createClient(clientID);
+  }
 
 }
Index: code/branches/network3/src/network/Server.h
===================================================================
--- code/branches/network3/src/network/Server.h	(revision 1200)
+++ code/branches/network3/src/network/Server.h	(revision 1232)
@@ -73,4 +73,5 @@
     bool sendGameState();
     void processAck( ack *data, int clientID);
+    bool processConnectRequest( connectRequest *con, int clientID );
     ConnectionManager *connection;
     GameStateManager *gamestates;
Index: code/branches/network3/src/network/Synchronisable.cc
===================================================================
--- code/branches/network3/src/network/Synchronisable.cc	(revision 1200)
+++ code/branches/network3/src/network/Synchronisable.cc	(revision 1232)
@@ -48,4 +48,8 @@
 namespace network
 {
+  
+  
+  int Synchronisable::state_=1; // detemines wheter we are server (default) or client
+  
   /**
   * Constructor:
@@ -63,4 +67,11 @@
   Synchronisable::~Synchronisable(){
   }
+  
+  void Synchronisable::setClient(bool b){
+    if(b) // client
+      state_=0x2;
+    else  // server
+      state_=0x1;
+  }
 
   /**
@@ -70,9 +81,10 @@
   * @param size size of the datatype the variable consists of
   */
-  void Synchronisable::registerVar(void *var, int size, variableType t){
+  void Synchronisable::registerVar(void *var, int size, variableType t, int mode){
     // create temporary synch.Var struct
     synchronisableVariable *temp = new synchronisableVariable;
     temp->size = size;
     temp->var = var;
+    temp->mode = mode; 
     temp->type = t;
     COUT(5) << "Syncronisable::registering var with size: " << temp->size << " and type: " << temp->type << std::endl; 
@@ -153,4 +165,6 @@
     for(i=syncList->begin(); n<datasize && i!=syncList->end(); ++i){
       //(std::memcpy(retVal.data+n, (const void*)(&(i->size)), sizeof(int));
+      if( ((*i)->mode & state_) == 0 )
+        continue;  // this variable should only be received
       switch((*i)->type){
       case DATA:
@@ -185,4 +199,6 @@
     COUT(5) << "Synchronisable: objectID " << vars.objectID << ", classID " << vars.classID << " size: " << vars.length << " synchronising data" << std::endl;
     for(i=syncList->begin(); i!=syncList->end(); i++){
+      if( ((*i)->mode ^ state_) == 0 )
+        continue;  // this variable should only be sent
       COUT(5) << "Synchronisable: element size: " << (*i)->size << " type: " << (*i)->type << std::endl;
       switch((*i)->type){
@@ -212,4 +228,6 @@
     std::list<synchronisableVariable *>::iterator i;
     for(i=syncList->begin(); i!=syncList->end(); i++){
+      if( ((*i)->mode & state_) == 0 )
+        continue;  // this variable should only be received, so dont add its size to the send-size
       switch((*i)->type){
       case DATA:
@@ -226,4 +244,12 @@
     return tsize;
   }
-
+  
+  void Synchronisable::setBacksync(bool sync){
+    backsync_=sync;
+  }
+
+  bool Synchronisable::getBacksync(){
+    return backsync_;
+  }
+  
 }
Index: code/branches/network3/src/network/Synchronisable.h
===================================================================
--- code/branches/network3/src/network/Synchronisable.h	(revision 1200)
+++ code/branches/network3/src/network/Synchronisable.h	(revision 1232)
@@ -62,4 +62,5 @@
   typedef struct synchronisableVariable{
     int size;
+    int mode; // this determines in which direction the variable gets synchronised
     void *var;
     variableType type;
@@ -69,5 +70,6 @@
   /**
   * This class is the base class of all the Objects in the universe that need to be synchronised over the network
-  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list. Additionally it also has to provide a Constructor, that takes exactly the variables in this linked list.
+   * Every class, t
+  int mode;hat inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list. Additionally it also has to provide a Constructor, that takes exactly the variables in this linked list.
   * @author Oliver Scheuss
   */
@@ -79,11 +81,14 @@
     int classID;
 
-    void registerVar(void *var, int size, variableType t);
+    void registerVar(void *var, int size, variableType t, int mode=1);
     //  syncData getData();
     syncData getData(unsigned char *mem);
     int getSize();
     bool updateData(syncData vars);
+    void setBacksync(bool sync);
+    bool getBacksync();
     virtual void registerAllVariables()=0;
     virtual bool create()=0;
+    static void setClient(bool b);
   protected:
     Synchronisable();
@@ -93,4 +98,6 @@
     std::list<synchronisableVariable *> *syncList;
     int datasize;
+    static int state_; // detemines wheter we are server (default) or client
+    bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
   };
 }
