Index: code/trunk/src/network/packet/Gamestate.cc
===================================================================
--- code/trunk/src/network/packet/Gamestate.cc	(revision 1747)
+++ code/trunk/src/network/packet/Gamestate.cc	(revision 1751)
@@ -41,6 +41,5 @@
 namespace packet {
 
-
-#define GAMESTATE_START(data) data + sizeof(GamestateHeader)
+#define GAMESTATE_START(data) (data + sizeof(GamestateHeader))
 #define GAMESTATE_HEADER(data) ((GamestateHeader *)data)
 #define HEADER GAMESTATE_HEADER(data_)
@@ -63,13 +62,11 @@
 {
   int tempsize=0, currentsize=0;
-  assert(data_==0 /*&& bs_==0*/);
-  int size = calcGamestateSize(mode);
+  assert(data_==0);
+  int size = calcGamestateSize(id, mode);
 
   COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl;
-    //retval->data = (unsigned char*)malloc(size);
   if(size==0)
     return false;
   data_ = new unsigned char[size + sizeof(GamestateHeader)];
-  //bs_ = new Bytestream(data_+sizeof(GamestateHeader), size);
   if(!data_){
     COUT(2) << "GameStateManager: could not allocate memory" << std::endl;
@@ -82,5 +79,5 @@
   orxonox::ObjectList<Synchronisable>::iterator it;
   for(it = orxonox::ObjectList<Synchronisable>::begin(); it; ++it){
-    tempsize=it->getSize2(mode);
+    tempsize=it->getSize2(id, mode);
 
     if(currentsize+tempsize > size){
@@ -90,5 +87,5 @@
       int addsize=tempsize;
       while(++temp)
-        addsize+=temp->getSize2(mode);
+        addsize+=temp->getSize2(id, mode);
       data_ = (unsigned char *)realloc(data_, sizeof(GamestateHeader) + currentsize + addsize);
       if(!data_)
@@ -97,5 +94,5 @@
     }// stop allocate additional memory
 
-    if(!it->getData2(mem, mode))
+    if(!it->getData(mem, id, mode))
       return false; // mem pointer gets automatically increased because of call by reference
     // increase size counter by size of current synchronisable
@@ -121,5 +118,7 @@
 bool Gamestate::spreadData(int mode)
 {
-  assert(data_ && !HEADER->compressed && !HEADER->diffed);
+  assert(data_);
+  assert(!HEADER->compressed);
+  assert(!HEADER->diffed);
   unsigned int size, objectID, classID;
   unsigned char *mem=data_+sizeof(GamestateHeader);
@@ -142,5 +141,5 @@
         //fabricate the new synchronisable
         if(!Synchronisable::fabricate(mem, mode))
-          /*return false*/;
+          return false;
         it=orxonox::ObjectList<Synchronisable>::end();
       }
@@ -175,4 +174,19 @@
 }
 
+bool Gamestate::operator==(packet::Gamestate gs){
+  unsigned char *d1 = data_+sizeof(GamestateHeader);
+  unsigned char *d2 = gs.data_+sizeof(GamestateHeader);
+  assert(!isCompressed());
+  assert(!gs.isCompressed());
+  while(d1<data_+HEADER->normsize)
+  {
+    if(*d1!=*d2)
+      return false;
+    d1++;
+    d2++;
+  }
+  return true;
+}
+
 bool Gamestate::process()
 {
@@ -183,5 +197,6 @@
 {
   assert(HEADER);
-  uLongf buffer = (uLongf)((HEADER->normsize + 12)*1.01)+1;
+  assert(!HEADER->compressed);
+  uLongf buffer = (uLongf)(((HEADER->normsize + 12)*1.01)+1);
   if(buffer==0)
     return false;
@@ -189,19 +204,30 @@
   unsigned char *ndata = new unsigned char[buffer+sizeof(GamestateHeader)];
   unsigned char *dest = GAMESTATE_START(ndata);
+  //unsigned char *dest = new unsigned char[buffer];
+  unsigned char *source = GAMESTATE_START(data_);
   int retval;
-  retval = compress( dest, &buffer, GAMESTATE_START(data_), (uLong)(HEADER->normsize) );
+  retval = compress( dest, &buffer, source, (uLong)(HEADER->normsize) );
   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 false;
-    case Z_BUF_ERROR: COUT(2) << "G.St.Man: compress: not enough memory available in the buffer in gamestate.compress" << std::endl;
-    return false;
-    case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl;
-    return false;
-  }
+    case Z_MEM_ERROR: COUT(1) << "G.St.Man: compress: not enough memory available in gamestate.compress" << std::endl; return false;
+    case Z_BUF_ERROR: COUT(2) << "G.St.Man: compress: not enough memory available in the buffer in gamestate.compress" << std::endl; return false;
+    case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl; return false;
+  }
+#ifndef NDEBUG
+  //decompress and compare the start and the decompressed data
+  unsigned char *rdata = new unsigned char[HEADER->normsize+sizeof(GamestateHeader)];
+  unsigned char *d2 = GAMESTATE_START(rdata);
+  uLongf length2 = HEADER->normsize;
+  uncompress(d2, &length2, dest, buffer);
+  for(unsigned int i=0; i<HEADER->normsize; i++){
+    assert(*(source+i)==*(d2+i));
+  }
+  delete[] rdata;
+#endif
 
   //copy and modify header
-  HEADER->compsize = buffer;
-  HEADER->compressed = true;
+#ifndef NDEBUG
+  HEADER->crc32 = calcCRC(data_+sizeof(GamestateHeader), HEADER->normsize);
+#endif
   *GAMESTATE_HEADER(ndata) = *HEADER;
   //delete old data
@@ -209,4 +235,6 @@
   //save new data
   data_ = ndata;
+  HEADER->compsize = buffer;
+  HEADER->compressed = true;
   assert(HEADER->compressed);
   COUT(3) << "gamestate compress normsize: " << HEADER->normsize << " compsize: " << HEADER->compsize << std::endl;
@@ -215,20 +243,19 @@
 bool Gamestate::decompressData()
 {
+  assert(HEADER);
   assert(HEADER->compressed);
-  //COUT(4) << "GameStateClient: uncompressing gamestate. id: " << a->id << ", baseid: " << a->base_id << ", normsize: " << a->normsize << ", compsize: " << a->compsize << std::endl;
-  int normsize = HEADER->normsize;
-  int compsize = HEADER->compsize;
-  int bufsize;
-  if(normsize < compsize)
-    bufsize = compsize;
-  else
-    bufsize = normsize;
-  if(bufsize==0)
-    return false;
+  COUT(3) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", normsize: " << HEADER->normsize << ", compsize: " << HEADER->compsize << std::endl;
+  unsigned int normsize = HEADER->normsize;
+  unsigned int compsize = HEADER->compsize;
+  unsigned int bufsize;
+  assert(compsize<=normsize);
+  bufsize = normsize;
+  assert(bufsize!=0);
   unsigned char *ndata = new unsigned char[bufsize + sizeof(GamestateHeader)];
   unsigned char *dest = ndata + sizeof(GamestateHeader);
+  unsigned char *source = data_ + sizeof(GamestateHeader);
   int retval;
-  uLongf length=normsize;
-  retval = uncompress( dest, &length, data_+sizeof(GamestateHeader), (uLong)compsize );
+  uLongf length=bufsize;
+  retval = uncompress( dest, &length, source, (uLong)compsize );
   switch ( retval ) {
     case Z_OK: COUT(5) << "successfully decompressed" << std::endl; break;
@@ -237,14 +264,17 @@
     case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return false;
   }
-
-  HEADER->compressed = false;
+#ifndef NDEBUG
+  assert(HEADER->crc32==calcCRC(ndata+sizeof(GamestateHeader), HEADER->normsize));
+#endif
+  
   //copy over the header
   *GAMESTATE_HEADER(ndata) = *HEADER;
   //delete old (compressed data)
   delete[] data_;
-  //set new pointers and create bytestream
+  //set new pointers
   data_ = ndata;
-  //bs_ = new Bytestream(getGs(), GAMESTATE_HEADER->normsize);
-
+  HEADER->compressed = false;
+  assert(HEADER->normsize==normsize);
+  assert(HEADER->compsize==compsize);
   return true;
 }
@@ -252,4 +282,7 @@
 Gamestate *Gamestate::diff(Gamestate *base)
 {
+  assert(HEADER);
+  assert(!HEADER->compressed);
+  assert(!HEADER->diffed);
   //unsigned char *basep = base->getGs()/*, *gs = getGs()*/;
   unsigned char *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
@@ -277,5 +310,8 @@
   *GAMESTATE_HEADER(ndata) = *HEADER;
   GAMESTATE_HEADER(ndata)->diffed = true;
-  Gamestate *g = new Gamestate(ndata, 0);
+  GAMESTATE_HEADER(ndata)->base_id = base->getID();
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
   return g;
 }
@@ -283,5 +319,6 @@
 Gamestate *Gamestate::undiff(Gamestate *base)
 {
-  assert(this && base);
+  assert(this && base);assert(HEADER);
+  assert(HEADER->diffed);
   assert(!HEADER->compressed && !GAMESTATE_HEADER(base->data_)->compressed);
   //unsigned char *basep = base->getGs()/*, *gs = getGs()*/;
@@ -310,10 +347,14 @@
   *GAMESTATE_HEADER(ndata) = *HEADER;
   GAMESTATE_HEADER(ndata)->diffed = false;
-  Gamestate *g = new Gamestate(ndata, 0);
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(!g->isDiffed());
+  assert(!g->isCompressed());
   return g;
 }
 
 
-unsigned int Gamestate::calcGamestateSize(int mode)
+unsigned int Gamestate::calcGamestateSize(unsigned int id, int mode)
 {
   int size=0;
@@ -322,5 +363,5 @@
     // get total size of gamestate
   for(it = orxonox::ObjectList<Synchronisable>::begin(); it; ++it)
-    size+=it->getSize2(mode); // size of the actual data of the synchronisable
+    size+=it->getSize2(id, mode); // size of the actual data of the synchronisable
 //  size+=sizeof(GamestateHeader);
   return size;
@@ -342,4 +383,8 @@
   }
 
+  bool Gamestate::isCompressed(){
+    return HEADER->compressed;
+  }
+  
   int Gamestate::getBaseID(){
     return HEADER->base_id;
