Index: /code/branches/network/src/network/GamestateClient.cc
===================================================================
--- /code/branches/network/src/network/GamestateClient.cc	(revision 1826)
+++ /code/branches/network/src/network/GamestateClient.cc	(revision 1827)
@@ -189,5 +189,5 @@
         return 0;
       }
-//      assert(base); //TODO: fix this
+//       assert(base); //TODO: fix this
       packet::Gamestate *undiffed = gs->undiff(base);
       delete gs;
Index: /code/branches/network/src/network/GamestateManager.cc
===================================================================
--- /code/branches/network/src/network/GamestateManager.cc	(revision 1826)
+++ /code/branches/network/src/network/GamestateManager.cc	(revision 1827)
@@ -133,4 +133,5 @@
     gs = reference->doSelection(clientID);
 //     gs = new packet::Gamestate(*reference);
+//     gs = new packet::Gamestate(*reference);
     // save the (undiffed) gamestate in the clients gamestate map
     gamestateMap_[clientID].insert(std::pair<int, packet::Gamestate*>(gs->getID(), gs));
Index: /code/branches/network/src/network/Synchronisable.cc
===================================================================
--- /code/branches/network/src/network/Synchronisable.cc	(revision 1826)
+++ /code/branches/network/src/network/Synchronisable.cc	(revision 1827)
@@ -120,16 +120,13 @@
   Synchronisable *Synchronisable::fabricate(unsigned char*& mem, int mode)
   {
-    unsigned int size, objectID, classID;
-    size = *(unsigned int *)mem;
-    objectID = *(unsigned int*)(mem+sizeof(unsigned int));
-    classID = *(unsigned int*)(mem+2*sizeof(unsigned int));
-    
-    orxonox::Identifier* id = GetIdentifier(classID);
+    synchronisableHeader *header = (synchronisableHeader *)mem;
+    
+    orxonox::Identifier* id = GetIdentifier(header->classID);
     assert(id);
     orxonox::BaseObject *bo = id->fabricate();
     Synchronisable *no = dynamic_cast<Synchronisable *>(bo);
     assert(no);
-    no->objectID=objectID;
-    no->classID=classID;
+    no->objectID=header->objectID;
+    no->classID=header->classID;
     COUT(3) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
           // update data and create object/entity...
@@ -228,11 +225,11 @@
     
     // start copy header
-    memcpy(mem, &size, sizeof(unsigned int));
-    mem+=sizeof(unsigned int);
-    memcpy(mem, &(this->objectID), sizeof(unsigned int));
-    mem+=sizeof(unsigned int);
-    memcpy(mem, &(this->classID), sizeof(unsigned int));
-    mem+=sizeof(unsigned int);
-    tempsize+=12;
+    synchronisableHeader *header = (synchronisableHeader *)mem;
+    header->size = size;
+    header->objectID = this->objectID;
+    header->classID = this->classID;
+    header->dataAvailable = true;
+    tempsize+=sizeof(synchronisableHeader);
+    mem+=sizeof(synchronisableHeader);
     // end copy header
     
@@ -241,5 +238,4 @@
     // copy to location
     for(i=syncList->begin(); i!=syncList->end(); ++i){
-      //(std::memcpy(retVal.data+n, (const void*)(&(i->size)), sizeof(int));
       if( ((*i)->mode & mode) == 0 ){
         COUT(5) << "not getting data: " << std::endl;
@@ -284,19 +280,18 @@
     unsigned char *data=mem;
     // start extract header
-    if(!isMyData(mem))
+    synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
+    assert(syncHeader->objectID==this->objectID);
+    if(syncHeader->dataAvailable==false){
+      mem+=syncHeader->size;
       return true;
-    unsigned int objectID, classID, size;
-    size = *(int *)mem;
-    mem+=sizeof(size);
-    objectID = *(int *)mem;
-    mem+=sizeof(objectID);
-    classID = *(int *)mem;
-    mem+=sizeof(classID);
+    }
+    
+    mem+=sizeof(synchronisableHeader);
     // stop extract header
-    assert(this->objectID==objectID);
-    assert(this->classID==classID);
-    
-    COUT(5) << "Synchronisable: objectID " << objectID << ", classID " << classID << " size: " << size << " synchronising data" << std::endl;
-    for(i=syncList->begin(); i!=syncList->end() && mem <= data+size; i++){
+    assert(this->objectID==syncHeader->objectID);
+//    assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?
+    
+    COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl;
+    for(i=syncList->begin(); i!=syncList->end() && mem <= data+syncHeader->size; i++){
       if( ((*i)->mode ^ mode) == 0 ){
         COUT(5) << "synchronisable: not updating variable " << std::endl;
@@ -382,14 +377,7 @@
   bool Synchronisable::isMyData(unsigned char* mem)
   {
-    unsigned int objectID, classID, size;
-    size = *(int *)mem;
-    mem+=sizeof(size);
-    objectID = *(int *)mem;
-    mem+=sizeof(objectID);
-    classID = *(int *)mem;
-    mem+=sizeof(classID);
-    
-    assert(classID == this->classID);
-    return (objectID == this->objectID);
+    synchronisableHeader *header = (synchronisableHeader *)mem;
+    assert(header->objectID==this->objectID);
+    return header->dataAvailable;
   }
   
Index: /code/branches/network/src/network/Synchronisable.h
===================================================================
--- /code/branches/network/src/network/Synchronisable.h	(revision 1826)
+++ /code/branches/network/src/network/Synchronisable.h	(revision 1827)
@@ -62,4 +62,5 @@
   struct synchronisableHeader{
     unsigned int size;
+    bool dataAvailable;
     unsigned int objectID;
     unsigned int classID;
Index: /code/branches/network/src/network/packet/Gamestate.cc
===================================================================
--- /code/branches/network/src/network/packet/Gamestate.cc	(revision 1826)
+++ /code/branches/network/src/network/packet/Gamestate.cc	(revision 1827)
@@ -101,6 +101,6 @@
     }// stop allocate additional memory
 
-    if(it->doSelection(id))
-      dataMap_[*it]=mem;  // save the mem location of the synchronisable data
+    //if(it->doSelection(id))
+    dataMap_[mem-data_]=(*it);  // save the mem location of the synchronisable data
     if(!it->getData(mem, id, mode))
       return false; // mem pointer gets automatically increased because of call by reference
@@ -130,5 +130,4 @@
   assert(!HEADER->compressed);
   assert(!HEADER->diffed);
-  unsigned int size, objectID, classID;
   unsigned char *mem=data_+sizeof(GamestateHeader);
     // get the start of the Synchronisable list
@@ -138,9 +137,7 @@
   // update the data of the objects we received
   while(mem < data_+sizeof(GamestateHeader)+HEADER->datasize){
-    size = *(unsigned int *)mem;
-    objectID = *(unsigned int*)(mem+sizeof(unsigned int));
-    classID = *(unsigned int*)(mem+2*sizeof(unsigned int));
-
-    s = Synchronisable::getSynchronisable( objectID );
+    synchronisableHeader *objectheader = (synchronisableHeader*)mem;
+
+    s = Synchronisable::getSynchronisable( objectheader->objectID );
     if(!s)
     {
@@ -195,4 +192,6 @@
   return GamestateHandler::addGamestate(this, getClientID());
 }
+
+
 
 bool Gamestate::compressData()
@@ -321,26 +320,165 @@
 Gamestate* Gamestate::doSelection(unsigned int clientID){
   assert(data_);
-  std::map<Synchronisable *, unsigned char *>::iterator it;
-  unsigned char *ndata, *tdata;
-  unsigned int nsize=0;
-  // calculate the size of the new gamestate
+  std::map<unsigned int, Synchronisable *>::iterator it;
+  
+  Gamestate *gs = new Gamestate(*this);
+  unsigned char *ndata = gs->data_ + sizeof(GamestateHeader);
+  synchronisableHeader *objectheader;
+  unsigned int objectOffset;
+  
+  //copy in the zeros
   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
-    if(it->first->doSelection(HEADER->id))
-      nsize+=*(unsigned int*)it->second;
-  }
-  ndata = new unsigned char[nsize+sizeof(GamestateHeader)];
-  tdata = ndata;
-  tdata += sizeof(GamestateHeader);
+    objectheader = (synchronisableHeader*)ndata;
+    unsigned int objectsize = objectheader->size;
+    assert(it->second->objectID==objectheader->objectID);
+    objectOffset=sizeof(unsigned int)+sizeof(bool); //skip the size and the availableDate variables in the objectheader
+    if(!it->second->doSelection(HEADER->id)){
+      while(objectOffset<objectsize){
+        objectheader->dataAvailable=false;
+        *(ndata+objectOffset)=0;    // set to 0
+        objectOffset++;
+      }
+      assert(objectOffset==objectsize);
+    }
+    ndata+=objectsize;
+  }
+  return gs;
+}
+
+
+Gamestate* Gamestate::intelligentDiff(Gamestate *base, unsigned int clientID){
+  // asserts
+  assert(data_);
+  assert(base->data_);
+  assert(!GAMESTATE_HEADER(base->data_)->diffed);
+  assert(!GAMESTATE_HEADER(base->data_)->compressed);
+  assert(!HEADER->compressed);
+  assert(!HEADER->diffed);
+  
+  //preparations
+  std::map<unsigned int, Synchronisable *>::iterator it;
+  unsigned char *origdata, *basedata, *destdata, *ndata;
+  unsigned int objectOffset, streamOffset=0;    //data offset
+  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 
+  synchronisableHeader *origheader;
+  synchronisableHeader *destheader;
+  
+  origdata = GAMESTATE_START(this->data_);
+  basedata = GAMESTATE_START(base->data_);
+  ndata = new unsigned char[HEADER->datasize + sizeof(GamestateHeader)];
+  destdata = ndata + sizeof(GamestateHeader);
+  
+  // do the diff
   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
-    if(it->first->doSelection(HEADER->id)){
-      memcpy(tdata, it->second, *(unsigned int*)it->second); // copy over the saved data of the synchronisable
-      tdata += *(unsigned int*)it->second;
-    }
-  }
-  COUT(3) << "oldsize: " << HEADER->datasize << " newsize: " << nsize << std::endl;
+    assert(streamOffset<HEADER->datasize);
+    bool sendData = it->second->doSelection(HEADER->id);
+    origheader = (synchronisableHeader *)(origdata+streamOffset);
+    destheader = (synchronisableHeader *)(destdata+streamOffset);
+    
+    //copy and partially diff the object header
+    assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
+    *(unsigned int*)destdata = *(unsigned int*)origdata; //size (do not diff)
+    *(bool*)(destdata+sizeof(unsigned int)) = sendData;
+    if(sendData){
+      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+sizeof(unsigned int)+sizeof(bool)); //objectid (diff it)
+      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+2*sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+2*sizeof(unsigned int)+sizeof(bool)); //classid (diff it)
+    }else{
+      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;
+      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0; 
+    }
+    objectOffset=sizeof(synchronisableHeader);
+    streamOffset+=sizeof(synchronisableHeader);
+    
+    //now handle the object data or fill with zeros
+    while(objectOffset<origheader->size ){
+      
+      if(sendData && streamOffset<minsize)
+        *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
+      else if(sendData)
+        *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
+      else
+        *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
+      
+      objectOffset++;
+      streamOffset++;
+    }
+    destdata+=objectOffset;
+    origdata+=objectOffset;
+    basedata+=objectOffset;
+  }
+  
+  //copy over the gamestate header and set the diffed flag
   *(GamestateHeader *)ndata = *HEADER; //copy over the header
-  GAMESTATE_HEADER(ndata)->datasize = nsize;
   Gamestate *gs = new Gamestate(ndata);
-  assert(HEADER->datasize>=nsize);
+  GAMESTATE_HEADER(ndata)->diffed=true;
+  return gs;
+}
+
+Gamestate* Gamestate::intelligentUnDiff(Gamestate *base){
+  // asserts
+  assert(data_);
+  assert(base->data_);
+  assert(!GAMESTATE_HEADER(base->data_)->diffed);
+  assert(!GAMESTATE_HEADER(base->data_)->compressed);
+  assert(!HEADER->compressed);
+  assert(HEADER->diffed);
+  
+  //preparations
+  std::map<unsigned int, Synchronisable *>::iterator it;
+  unsigned char *origdata, *basedata, *destdata, *ndata;
+  unsigned int objectOffset, streamOffset=0;    //data offset
+  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 
+  synchronisableHeader *origheader;
+  synchronisableHeader *destheader;
+  
+  origdata = GAMESTATE_START(this->data_);
+  basedata = GAMESTATE_START(base->data_);
+  ndata = new unsigned char[HEADER->datasize + sizeof(GamestateHeader)];
+  destdata = ndata + sizeof(GamestateHeader);
+  
+  // do the undiff
+  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
+    assert(streamOffset<HEADER->datasize);
+    origheader = (synchronisableHeader *)(origdata+streamOffset);
+    destheader = (synchronisableHeader *)(destdata+streamOffset);
+    bool sendData;
+    
+    //copy and partially diff the object header
+    assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
+    *(unsigned int*)destdata = *(unsigned int*)origdata; //size (do not diff)
+    *(bool*)(destdata+sizeof(unsigned int)) = *(bool*)(origdata+sizeof(unsigned int));
+    sendData = *(bool*)(origdata+sizeof(unsigned int));
+    if(sendData){
+      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+sizeof(unsigned int)+sizeof(bool)); //objectid (diff it)
+      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+2*sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+2*sizeof(unsigned int)+sizeof(bool)); //classid (diff it)
+    }else{
+      *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;
+      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0; 
+    }
+    objectOffset=sizeof(synchronisableHeader);
+    streamOffset+=sizeof(synchronisableHeader);
+    
+    //now handle the object data or fill with zeros
+    while(objectOffset<origheader->size ){
+      
+      if(sendData && streamOffset<minsize)
+        *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
+      else if(sendData)
+        *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
+      else
+        *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
+      
+      objectOffset++;
+      streamOffset++;
+    }
+    destdata+=objectOffset;
+    origdata+=objectOffset;
+    basedata+=objectOffset;
+  }
+  
+  //copy over the gamestate header and set the diffed flag
+  *(GamestateHeader *)ndata = *HEADER; //copy over the header
+  Gamestate *gs = new Gamestate(ndata);
+  GAMESTATE_HEADER(ndata)->diffed=false;
   return gs;
 }
Index: /code/branches/network/src/network/packet/Gamestate.h
===================================================================
--- /code/branches/network/src/network/packet/Gamestate.h	(revision 1826)
+++ /code/branches/network/src/network/packet/Gamestate.h	(revision 1827)
@@ -74,6 +74,8 @@
     int getBaseID();
     Gamestate *diff(Gamestate *base);
+    Gamestate* intelligentDiff(Gamestate *base, unsigned int clientID);
+    Gamestate *undiff(Gamestate *base);
+    Gamestate* intelligentUnDiff(Gamestate *base);
     Gamestate* doSelection(unsigned int clientID);
-    Gamestate *undiff(Gamestate *base);
     bool compressData();
     bool decompressData();
@@ -88,5 +90,5 @@
     unsigned int calcGamestateSize(unsigned int id, int mode=0x0);
     void removeObject(orxonox::ObjectListIterator<Synchronisable> &it);
-    std::map<Synchronisable *, unsigned char *> dataMap_;
+    std::map<unsigned int, Synchronisable*> dataMap_;
 };
 
