Index: /code/trunk/src/network/Client.cc
===================================================================
--- /code/trunk/src/network/Client.cc	(revision 1750)
+++ /code/trunk/src/network/Client.cc	(revision 1751)
@@ -61,4 +61,5 @@
     isSynched_=false;
     gameStateFailure_=false;
+    isServer_ = false;
   }
 
@@ -72,4 +73,5 @@
     isSynched_=false;
     gameStateFailure_=false;
+    isServer_ = false;
   }
 
@@ -83,4 +85,5 @@
     isSynched_=false;
     gameStateFailure_=false;
+    isServer_ = false;
   }
 
@@ -151,5 +154,5 @@
     if(client_connection.isConnected() && isSynched_){
       COUT(4) << "popping partial gamestate: " << std::endl;
-      /*packet::Gamestate *gs = gamestate.getGamestate();
+      packet::Gamestate *gs = gamestate.getGamestate();
       if(gs){
         COUT(4) << "client tick: sending gs " << gs << std::endl;
@@ -157,5 +160,5 @@
           COUT(3) << "Problem adding partial gamestate to queue" << std::endl;
         // gs gets automatically deleted by enet callback
-      }*/
+      }
     }
     ENetEvent *event;
@@ -168,8 +171,8 @@
     }
     int gameStateID = gamestate.processGamestates();
-    /*if(gameStateID==GAMESTATEID_INITIAL)
+    if(gameStateID==GAMESTATEID_INITIAL)
       if(gameStateFailure_){
-        packet::Acknowledgement ack(GAMESTATEID_INITIAL, 0);
-        if(!ack.send())
+        packet::Acknowledgement *ack = new packet::Acknowledgement(GAMESTATEID_INITIAL, 0);
+        if(!ack->send())
           COUT(3) << "could not (negatively) ack gamestate" << std::endl;
         else 
@@ -183,8 +186,8 @@
         isSynched_=true;
       gameStateFailure_=false;
-      packet::Acknowledgement ack(gameStateID, 0);
-      if(!ack.send())
+      packet::Acknowledgement *ack = new packet::Acknowledgement(gameStateID, 0);
+      if(!ack->send())
         COUT(3) << "could not ack gamestate" << std::endl;
-    }*/// otherwise we had no gamestate to load
+    }// otherwise we had no gamestate to load
     gamestate.cleanup();
     return;
Index: /code/trunk/src/network/GamestateClient.cc
===================================================================
--- /code/trunk/src/network/GamestateClient.cc	(revision 1750)
+++ /code/trunk/src/network/GamestateClient.cc	(revision 1751)
@@ -75,9 +75,14 @@
     int id = GAMESTATEID_INITIAL;
     bool b = saveShipCache();
-    if(processGamestate(tempGamestate_)){
-      if(b)
-        loadShipCache();
-      id = tempGamestate_->getID();
-    }
+    packet::Gamestate *processed = processGamestate(tempGamestate_);
+    assert(processed);
+    //successfully loaded data from gamestate. now save gamestate for diff and delete the old gs
+    tempGamestate_=0;
+    gamestateMap_[processed->getID()]=processed;
+    last_diff_ = processed->getBaseID();
+    last_gamestate_ = processed->getID();
+    if(b)
+      loadShipCache();
+    id = processed->getID();
     cleanup();
     return id;
@@ -130,10 +135,10 @@
     if(myShip_){
       //      unsigned char *data = new unsigned char[myShip_->getSize()];
-      int size=myShip_->getSize(0x1);
+      int size=myShip_->getSize2(0, 0x1);
       if(size==0)
         return false;
       shipCache_ = new unsigned char [size];
       unsigned char *temp = shipCache_;
-      if(!myShip_->getData2(temp, 0x1))
+      if(!myShip_->getData(temp, 0, 0x1))
         COUT(3) << "could not save shipCache" << std::endl;
       return true;
@@ -152,9 +157,19 @@
   }
 
-  bool GamestateClient::processGamestate(packet::Gamestate *gs){
-    assert(gs->decompressData());
-    if(gs->isDiffed())
-      assert(gs->undiff(gamestateMap_[gs->getBaseID()]));
-    return gs->spreadData();
+  packet::Gamestate *GamestateClient::processGamestate(packet::Gamestate *gs){
+    if(gs->isCompressed())
+      assert(gs->decompressData());
+    if(gs->isDiffed()){
+      packet::Gamestate *base = gamestateMap_[gs->getBaseID()];
+      assert(base);
+      packet::Gamestate *undiffed = gs->undiff(base);
+      delete gs;
+      gs=undiffed;
+      COUT(3) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
+    }
+    if(gs->spreadData())
+      return gs;
+    else
+      return NULL;
   }
 
Index: /code/trunk/src/network/GamestateClient.h
===================================================================
--- /code/trunk/src/network/GamestateClient.h	(revision 1750)
+++ /code/trunk/src/network/GamestateClient.h	(revision 1751)
@@ -66,6 +66,6 @@
     void cleanup();
   private:
-    bool processGamestate(packet::Gamestate *gs);
-    void removeObject(orxonox::ObjectListIterator<Synchronisable> &it);
+    packet::Gamestate *processGamestate(packet::Gamestate *gs);
+    void removeObject(orxonox::ObjectList<Synchronisable>::iterator &it);
     void printGamestateMap();
     bool saveShipCache();
Index: /code/trunk/src/network/GamestateManager.cc
===================================================================
--- /code/trunk/src/network/GamestateManager.cc	(revision 1750)
+++ /code/trunk/src/network/GamestateManager.cc	(revision 1751)
@@ -129,27 +129,23 @@
     //why are we searching the same client's gamestate id as we searched in
     //Server::sendGameState?
+    packet::Gamestate *gs;
     int gID = ClientInformation::findClient(clientID)->getGamestateID();
-    COUT(4) << "G.St.Man: popgamestate: sending gstate_id: " << id_ << " diffed from: " << gID << std::endl;
-//     COUT(3) << "gamestatemap: " << &gameStateMap << std::endl;
+    //COUT(4) << "G.St.Man: popgamestate: sending gstate_id: " << id_ << " diffed from: " << gID << std::endl;
     //chose wheather the next gamestate is the first or not
     if(gID != GAMESTATEID_INITIAL){
-      // TODO something with the gamestatemap is wrong
       packet::Gamestate *client=NULL;
       std::map<int, packet::Gamestate*>::iterator it = gamestateMap.find(gID);
       if(it!=gamestateMap.end())
         client = it->second;
-      packet::Gamestate *gs;
       if(client)
         gs = reference->diff(client);
       else
         gs = new packet::Gamestate(*reference);
-      gs->compressData();
-      return gs;
     } else {
       COUT(4) << "we got a GAMESTATEID_INITIAL for clientID: " << clientID << std::endl;
-//       ackGameState(clientID, reference->id);
-      return new packet::Gamestate(*reference);
-      // return an undiffed gamestate and set appropriate flags
-    }
+      gs = new packet::Gamestate(*reference);
+    }
+    assert(gs->compressData());
+    return gs;
   }
   
@@ -194,9 +190,9 @@
     if(client->getGamestateID()>=0)
       gamestateUsed[client->getGamestateID()]--;
-    ClientInformation::removeClient(client->getID());
   }
   
   bool GamestateManager::processGamestate(packet::Gamestate *gs){
-    assert(gs->decompressData());
+    if(gs->isCompressed())
+       assert(gs->decompressData());
     assert(!gs->isDiffed());
     return gs->spreadData();
Index: /code/trunk/src/network/Host.cc
===================================================================
--- /code/trunk/src/network/Host.cc	(revision 1750)
+++ /code/trunk/src/network/Host.cc	(revision 1751)
@@ -1,2 +1,30 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
 #include <assert.h>
 
Index: /code/trunk/src/network/Host.h
===================================================================
--- /code/trunk/src/network/Host.h	(revision 1750)
+++ /code/trunk/src/network/Host.h	(revision 1751)
@@ -54,4 +54,5 @@
     virtual ~Host();
     static Host *instance_;
+    bool isServer_;	
 
   public:
@@ -64,4 +65,5 @@
     static void setClientID(unsigned int id){ instance_->clientID_ = id; }
     static void setShipID(unsigned int id){ instance_->shipID_ = id; }
+    static bool isServer(){ return instance_->isServer_; }		
   private:
     unsigned int clientID_;
Index: /code/trunk/src/network/Server.cc
===================================================================
--- /code/trunk/src/network/Server.cc	(revision 1750)
+++ /code/trunk/src/network/Server.cc	(revision 1751)
@@ -54,4 +54,5 @@
 #include "packet/Packet.h"
 #include "packet/Welcome.h"
+#include <util/Convert.h>
 
 namespace network
@@ -68,4 +69,5 @@
     connection = new ConnectionManager();
     gamestates_ = new GamestateManager();
+    isServer_ = true;
   }
 
@@ -74,4 +76,5 @@
     connection = new ConnectionManager(port);
     gamestates_ = new GamestateManager();
+    isServer_ = true;
   }
 
@@ -85,4 +88,5 @@
     connection = new ConnectionManager(port, bindAddress);
     gamestates_ = new GamestateManager();
+    isServer_ = true;
   }
 
@@ -96,4 +100,5 @@
     connection = new ConnectionManager(port, bindAddress);
     gamestates_ = new GamestateManager();
+    isServer_ = true;
   }
 
@@ -260,5 +265,4 @@
       //std::cout << "adding gamestate" << std::endl;
       gs->setClientID(cid);
-      assert(gs->compressData());
       if ( !gs->send() ){
         COUT(3) << "Server: packet with client id (cid): " << cid << " not sended: " << temp->getFailures() << std::endl;
@@ -294,6 +298,5 @@
       return false;
     }
-    if(temp->prev()->getBegin()) { //not good if you use anything else than insertBack
-      temp->prev()->setID(0); //bugfix: not necessary but usefull
+    if(temp==ClientInformation::getBegin()) { //not good if you use anything else than insertBack
       temp->setID(1);
     }
@@ -324,4 +327,9 @@
     w->setClientID(temp->getID());
     assert(w->send());
+    packet::Gamestate *g = new packet::Gamestate();
+    g->setClientID(temp->getID());
+    assert(g->collectData(0));
+    assert(g->compressData());
+    assert(g->send());
     return true;
   }
@@ -349,7 +357,6 @@
     no->setTransDamp(75);
     no->setRotDamp(1.0);
-    no->setCamera("cam_"+client->getID());
+    no->setCamera(std::string("cam_") + convertToString(client->getID()));
     no->create();
-    no->setBacksync(true);
 
     return true;
@@ -365,4 +372,5 @@
     if(!client)
       return false;
+    gamestates_->removeClient(client);
     while(it){
       if(it->objectID!=client->getShipID()){
Index: /code/trunk/src/network/Synchronisable.cc
===================================================================
--- /code/trunk/src/network/Synchronisable.cc	(revision 1750)
+++ /code/trunk/src/network/Synchronisable.cc	(revision 1751)
@@ -63,4 +63,6 @@
     static int idCounter=0;
     datasize=0;
+    objectFrequency_=1;
+    objectMode_=0x1; // by default do not send data to servere
     objectID=idCounter++;
     syncList = new std::list<synchronisableVariable *>;
@@ -81,4 +83,5 @@
   }
 
+  
   void Synchronisable::setClient(bool b){
     if(b) // client
@@ -95,7 +98,11 @@
     classID = *(unsigned int*)(mem+2*sizeof(unsigned int));
     
+    if(size==3*sizeof(unsigned int)) //not our turn, dont do anything
+      return true;
+    
     orxonox::Identifier* id = ID(classID);
     if(!id){
       COUT(3) << "We could not identify a new object; classid: " << classID << " uint: " << (unsigned int)classID << " objectID: " << objectID << " size: " << size << std::endl;
+      assert(0);
       return false; // most probably the gamestate is corrupted
     }
@@ -140,61 +147,10 @@
     syncList->push_back(temp);
   }
-
-
-  /**
-  * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct
-  * Difference to the above function:
-  * takes a pointer to already allocated memory (must have at least getSize bytes length)
-  * structure of the bitstream:
-  * (var1_size,var1,var2_size,var2,...)
-  * varx_size: size = sizeof(int)
-  * varx: size = varx_size
-  * @return data containing all variables and their sizes
-  */
-  syncData Synchronisable::getData(unsigned char *mem, int mode){
-    //std::cout << "inside getData" << std::endl;
-    if(mode==0x0)
-      mode=state_;
-    if(classID==0)
-      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
-    this->classID=this->getIdentifier()->getNetworkID();
-    std::list<synchronisableVariable *>::iterator i;
-    syncData retVal;
-    retVal.objectID=this->objectID;
-    retVal.classID=this->classID;
-    retVal.length=getSize();
-    COUT(5) << "Synchronisable getting data from objectID: " << retVal.objectID << " classID: " << retVal.classID << " length: " << retVal.length << std::endl;
-    retVal.data=mem;
-    // copy to location
-    int n=0; //offset
-    for(i=syncList->begin(); n<datasize && 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;
-        continue;  // this variable should only be received
-      }
-      switch((*i)->type){
-      case DATA:
-        memcpy( (void *)(retVal.data+n), (void*)((*i)->var), (*i)->size);
-        n+=(*i)->size;
-        break;
-      case STRING:
-        memcpy( (void *)(retVal.data+n), (void *)&((*i)->size), sizeof(int) );
-        n+=sizeof(int);
-        const char *data = ( ( *(std::string *) (*i)->var).c_str());
-        memcpy( retVal.data+n, (void*)data, (*i)->size);
-        COUT(5) << "synchronisable: char: " << (const char *)(retVal.data+n) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl;
-        n+=(*i)->size;
-        break;
-      }
-    }
-    return retVal;
-  }
   
   /**
    * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct
-  * Difference to the above function:
+   * Difference to the above function:
    * takes a pointer to already allocated memory (must have at least getSize bytes length)
-  * structure of the bitstream:
+   * structure of the bitstream:
    * (var1_size,var1,var2_size,var2,...)
    * varx_size: size = sizeof(int)
@@ -202,5 +158,5 @@
    * @return data containing all variables and their sizes
    */
-  bool Synchronisable::getData2(unsigned char*& mem, int mode){
+  bool Synchronisable::getData(unsigned char*& mem, unsigned int id, int mode){
     //std::cout << "inside getData" << std::endl;
     unsigned int tempsize = 0;
@@ -209,8 +165,8 @@
     if(classID==0)
       COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
-    this->classID=this->getIdentifier()->getNetworkID();
+    this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this
     std::list<synchronisableVariable *>::iterator i;
     unsigned int size;
-    size=getSize2(mode);
+    size=getSize2(id, mode);
     
     // start copy header
@@ -224,4 +180,7 @@
     // end copy header
     
+    //if this tick is we dont synchronise, then abort now
+    if(!isMyTick(id))
+      return true;
     
     COUT(5) << "Synchronisable getting data from objectID: " << objectID << " classID: " << classID << " length: " << size << std::endl;
@@ -254,91 +213,4 @@
   }
 
-  /*bool Synchronisable::getData(Bytestream& bs, int mode)
-  {
-    //std::cout << "inside getData" << std::endl;
-    if(mode==0x0)
-      mode=state_;
-    if(classID==0)
-      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
-    this->classID=this->getIdentifier()->getNetworkID();
-    std::list<synchronisableVariable *>::iterator i;
-    bs << this->getSize();
-    bs << this->objectID;
-    bs << this->classID;
-    // copy to location
-    for(i=syncList->begin(); i!=syncList->end(); ++i){
-      if( ((*i)->mode & mode) == 0 ){
-        COUT(5) << "not getting data: " << std::endl;
-        continue;  // this variable should only be received
-      }
-      switch((*i)->type){
-        case DATA:
-          bs << *(*i)->var;
-          //std::memcpy( (void *)(retVal.data+n), (void*)((*i)->var), (*i)->size);
-          //n+=(*i)->size;
-          break;
-        case STRING:
-          bs << *(String *)((*i)->var);
-          //memcpy( (void *)(retVal.data+n), (void *)&((*i)->size), sizeof(int) );
-          //n+=sizeof(int);
-          //const char *data = ( ( *(std::string *) (*i)->var).c_str());
-          //std::memcpy( retVal.data+n, (void*)data, (*i)->size);
-          //COUT(5) << "synchronisable: char: " << (const char *)(retVal.data+n) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl;
-          //n+=(*i)->size;
-          break;
-      }
-    }
-    return true;
-  }*/
-
-  
-  /**
-  * This function takes a syncData struct and takes it to update the variables
-  * @param vars data of the variables
-  * @return true/false
-  */
-  bool Synchronisable::updateData(syncData vars, int mode){
-    if(mode==0x0)
-      mode=state_;
-    unsigned char *data=vars.data;
-    std::list<synchronisableVariable *>::iterator i;
-    if(syncList->empty()){
-      COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
-      return false;
-    }
-    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 ^ mode) == 0 ){
-        COUT(5) << "synchronisable: not updating variable " << std::endl;
-        continue;  // this variable should only be set
-      }
-      COUT(5) << "Synchronisable: element size: " << (*i)->size << " type: " << (*i)->type << std::endl;
-      bool callback=false;
-      switch((*i)->type){
-      case DATA:
-        if((*i)->callback) // check whether this variable changed (but only if callback was set)
-          if(strncmp((char *)(*i)->var, (char *)data, (*i)->size)!=0)
-            callback=true;
-        memcpy((void*)(*i)->var, data, (*i)->size);
-        data+=(*i)->size;
-        break;
-      case STRING:
-        (*i)->size = *(int *)data;
-        COUT(5) << "string size: " << (*i)->size << std::endl;
-        data+=sizeof(int);
-        if((*i)->callback) // check whether this string changed
-          if( *(std::string *)((*i)->var) != std::string((char *)data) )
-            callback=true;
-        *((std::string *)((*i)->var)) = std::string((const char*)data);
-        COUT(5) << "synchronisable: char: " << (const char*)data << " string: " << std::string((const char*)data) << std::endl;
-        data += (*i)->size;
-        break;
-      }
-      // call the callback function, if defined
-      if(callback && (*i)->callback)
-        (*i)->callback->call();
-    }
-    return true;
-  }
   
   /**
@@ -368,4 +240,7 @@
     assert(this->objectID==objectID);
     assert(this->classID==classID);
+    if(size==3*sizeof(unsigned int)) //if true, only the header is available
+      return true;
+      //assert(0);
     
     COUT(5) << "Synchronisable: objectID " << objectID << ", classID " << classID << " size: " << size << " synchronising data" << std::endl;
@@ -408,5 +283,7 @@
   * @return amount of bytes
   */
-  int Synchronisable::getSize(int mode){
+  int Synchronisable::getSize(unsigned int id, int mode){
+    if(!isMyTick(id))
+      return 0;
     int tsize=0;
     if(mode==0x0)
@@ -435,6 +312,16 @@
    * @return amount of bytes
    */
-  int Synchronisable::getSize2(int mode){
-    return 3*sizeof(unsigned int) + getSize( mode );
+  int Synchronisable::getSize2(unsigned int id, int mode){
+    return sizeof(synchronisableHeader) + getSize( id, mode );
+  }
+  
+  /**
+   * 
+   * @param id 
+   * @return 
+   */
+  bool Synchronisable::isMyTick(unsigned int id){
+//     return true;
+    return ( id==0 || id%objectFrequency_==objectID%objectFrequency_ ) && ((objectMode_&state_)!=0);
   }
   
@@ -453,11 +340,9 @@
   }
   
-  void Synchronisable::setBacksync(bool sync){
-    backsync_=sync;
-  }
-
-  bool Synchronisable::getBacksync(){
-    return backsync_;
-  }
+  void Synchronisable::setObjectMode(int mode){
+    assert(mode==0x1 || mode==0x2 || mode==0x3);
+    objectMode_=mode;
+  }
+
 
 }
Index: /code/trunk/src/network/Synchronisable.h
===================================================================
--- /code/trunk/src/network/Synchronisable.h	(revision 1750)
+++ /code/trunk/src/network/Synchronisable.h	(revision 1751)
@@ -34,4 +34,5 @@
 #include <list>
 #include "core/OrxonoxClass.h"
+#include "util/XMLIncludes.h"
 #include "NetworkCallback.h"
 
@@ -43,9 +44,8 @@
   };
 
-  struct syncData{
-    unsigned int length;
+  struct synchronisableHeader{
+    unsigned int size;
     unsigned int objectID;
     unsigned int classID;
-    unsigned char *data;
   };
 
@@ -67,5 +67,5 @@
   class _NetworkExport Synchronisable : virtual public orxonox::OrxonoxClass{
   public:
-
+    
     virtual ~Synchronisable();
     unsigned int objectID;
@@ -73,15 +73,11 @@
 
     void registerVar(void *var, int size, variableType t, int mode=1, NetworkCallbackBase *cb=0);
-    //  syncData getData();
-    syncData getData(unsigned char *mem, int mode=0x0);
-    bool getData2(unsigned char*& men, int mode=0x0);
-    //bool getData(Bytestream& bs, int mode=0x0);
-    int getSize(int mode=0x0);
-    int getSize2(int mode=0x0);
-    bool updateData(syncData vars, int mode=0x0);
+    bool getData(unsigned char*& men, unsigned int id, int mode=0x0);
+    int getSize2(unsigned int id, int mode=0x0);
     bool updateData(unsigned char*& mem, int mode=0x0);
     bool isMyData(unsigned char* mem);
-    void setBacksync(bool sync);
-    bool getBacksync();
+    void setObjectMode(int mode);
+    void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; }
+    
     virtual void registerAllVariables()=0;
     virtual bool create();
@@ -92,10 +88,12 @@
     Synchronisable();
   private:
-    /*  bool removeObject(ObjectList<Synchronisable>::iterator it);*/
-
+    int getSize(unsigned int id, int mode=0x0);
+    bool isMyTick(unsigned int id);
     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)
+    unsigned int objectFrequency_;
+    int objectMode_;
   };
 }
Index: /code/trunk/src/network/packet/Acknowledgement.cc
===================================================================
--- /code/trunk/src/network/packet/Acknowledgement.cc	(revision 1750)
+++ /code/trunk/src/network/packet/Acknowledgement.cc	(revision 1751)
@@ -45,5 +45,5 @@
   data_=new unsigned char[ getSize() ];
   *(ENUM::Type *)(data_ + _PACKETID ) = ENUM::Acknowledgement;
-  *(unsigned int *)&data_[ _ACKID ] = id;
+  *(unsigned int *)(data_ + _ACKID ) = id;
   clientID_=clientID;
 }
Index: /code/trunk/src/network/packet/Gamestate.cc
===================================================================
--- /code/trunk/src/network/packet/Gamestate.cc	(revision 1750)
+++ /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;
Index: /code/trunk/src/network/packet/Gamestate.h
===================================================================
--- /code/trunk/src/network/packet/Gamestate.h	(revision 1750)
+++ /code/trunk/src/network/packet/Gamestate.h	(revision 1751)
@@ -29,5 +29,7 @@
 #include "Packet.h"
 #include "network/Synchronisable.h"
-//#include "util/Bytestream.h"
+#ifndef NDEBUG
+#include "util/CRC32.h"
+#endif
 #include "core/CoreIncludes.h"
 
@@ -48,4 +50,7 @@
   bool complete; // wheter it is a complete gamestate or only partial
   bool compressed;
+#ifndef NDEBUG
+  uint32_t crc32;
+#endif
 };
 
@@ -64,4 +69,5 @@
     int getID();
     bool isDiffed();
+    bool isCompressed();
     int getBaseID();
     Gamestate *diff(Gamestate *base);
@@ -74,8 +80,8 @@
     virtual bool process();
 
-
+    bool operator ==(packet::Gamestate gs);
   private:
-    unsigned int calcGamestateSize(int mode=0x0);
-    void removeObject(orxonox::ObjectListIterator<Synchronisable> &it);
+    unsigned int calcGamestateSize(unsigned int id, int mode=0x0);
+    void removeObject(orxonox::ObjectList<Synchronisable>::iterator &it);
 
 
Index: /code/trunk/src/network/packet/Packet.cc
===================================================================
--- /code/trunk/src/network/packet/Packet.cc	(revision 1750)
+++ /code/trunk/src/network/packet/Packet.cc	(revision 1751)
@@ -92,6 +92,8 @@
 
 Packet::~Packet(){
-  if(enetPacket_)
+  if(enetPacket_){
+    assert(enetPacket_->freeCallback==0);
     enet_packet_destroy(enetPacket_);
+  }
   if(data_)
     delete[] data_;
@@ -109,9 +111,10 @@
     }
     enetPacket_ = enet_packet_create(getData(), getSize(), getFlags());
-    //enetPacket_->freeCallback = &Packet::deletePacket;
-    enetPacket_->freeCallback = &blub;
+    enetPacket_->freeCallback = &Packet::deletePacket;
+//     enetPacket_->freeCallback = &blub;
     packetMap_[enetPacket_] = this;
   }
-  /*switch( *(ENUM::Type *)(data_ + _PACKETID) )
+#ifndef NDEBUG 
+  switch( *(ENUM::Type *)(data_ + _PACKETID) )
   {
     case ENUM::Acknowledgement:
@@ -120,12 +123,13 @@
     case ENUM::Gamestate:
     case ENUM::Welcome:
-      COUT(3) << "welcome" << std::endl;
-      p = new Welcome( data, clientID );
+      break;
     default:
-      assert(0); //TODO: repair this
+      assert(0); //there was some error, if this is the case
       break;
-  }*/
-  network::Host::addPacket( enetPacket_, clientID_);
+  }
+#endif
+  ENetPacket *temp = enetPacket_;
   enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
+  network::Host::addPacket( temp, clientID_);
   return true;
 }
@@ -168,4 +172,5 @@
 void Packet::deletePacket(ENetPacket *packet){
   assert(packetMap_[packet]);
+  assert(packetMap_[packet]->enetPacket_==0);
   delete packetMap_[packet];
 }
Index: /code/trunk/src/network/packet/Packet.h
===================================================================
--- /code/trunk/src/network/packet/Packet.h	(revision 1750)
+++ /code/trunk/src/network/packet/Packet.h	(revision 1751)
@@ -78,9 +78,9 @@
     enet_uint32 flags_;
     int clientID_;
+    ENUM::Direction packetDirection_;
     unsigned char *data_;
   private:
     static std::map<ENetPacket *, Packet *> packetMap_;
     ENetPacket *enetPacket_;
-    ENUM::Direction packetDirection_;
 };
 
Index: /code/trunk/src/network/packet/Welcome.cc
===================================================================
--- /code/trunk/src/network/packet/Welcome.cc	(revision 1750)
+++ /code/trunk/src/network/packet/Welcome.cc	(revision 1751)
@@ -32,4 +32,5 @@
 #include "Welcome.h"
 #include "network/Host.h"
+#include "network/Synchronisable.h"
 #include "core/CoreIncludes.h"
 #include <assert.h>
@@ -79,4 +80,5 @@
   Host::setShipID(shipID);
   COUT(3) << "Welcome set clientId: " << clientID << " shipID: " << shipID << std::endl;
+  Synchronisable::setClient(true);
   delete this;
   return true;
Index: /code/trunk/src/orxonox/objects/Model.cc
===================================================================
--- /code/trunk/src/orxonox/objects/Model.cc	(revision 1750)
+++ /code/trunk/src/orxonox/objects/Model.cc	(revision 1751)
@@ -45,8 +45,13 @@
     CreateFactory(Model);
 
+    /**
+     * 
+     */
     Model::Model()
     {
         RegisterObject(Model);
         registerAllVariables();
+        if(this->isExactlyA(Class(Model)))
+           setObjectFrequency(1);
     }
 
Index: /code/trunk/src/orxonox/objects/SpaceShip.cc
===================================================================
--- /code/trunk/src/orxonox/objects/SpaceShip.cc	(revision 1750)
+++ /code/trunk/src/orxonox/objects/SpaceShip.cc	(revision 1751)
@@ -78,5 +78,5 @@
           return *it;
       }
-      return 0;
+      assert(0);
     }
 
@@ -165,6 +165,9 @@
         if(network::Host::running())
           COUT(3) << "this id: " << this->objectID << " myShipID: " << network::Host::getShipID() << std::endl;
-        if(network::Host::running() && objectID == network::Host::getShipID())
+        if(network::Host::running() && objectID == network::Host::getShipID()){
+          if(!network::Host::isServer())
+ 	    setObjectMode(0x3);
           myShip_=true;
+        }
         else
           this->setRadarObjectColour(this->getProjectileColour());
@@ -242,16 +245,18 @@
 
         // START CREATING ADDITIONAL EFFECTS
-        this->backlight_ = new Backlight(this->maxSpeed_, 0.8);
-        this->attachObject(this->backlight_);
-        this->backlight_->setPosition(-2.35, 0, 0.2);
-        this->backlight_->setColour(this->getProjectileColour());
-
-        this->smoke_ = new ParticleSpawner();
-        this->smoke_->setParticle("Orxonox/smoke5", LODParticle::normal, 0, 0, 3);
-        this->attachObject(this->smoke_);
-
-        this->fire_ = new ParticleSpawner();
-        this->fire_->setParticle("Orxonox/fire3", LODParticle::normal, 0, 0, 1);
-        this->attachObject(this->fire_);
+        /*if(!network::Host::running() || network::Host::isServer()){
+          this->backlight_ = new Backlight(this->maxSpeed_, 0.8);
+          this->attachObject(this->backlight_);
+          this->backlight_->setPosition(-2.35, 0, 0.2);
+          this->backlight_->setColour(this->getProjectileColour());
+    
+          this->smoke_ = new ParticleSpawner();
+          this->smoke_->setParticle("Orxonox/smoke5", LODParticle::normal, 0, 0, 3);
+          this->attachObject(this->smoke_);
+    
+          this->fire_ = new ParticleSpawner();
+          this->fire_->setParticle("Orxonox/fire3", LODParticle::normal, 0, 0, 1);
+          this->attachObject(this->fire_);
+        }*/
         // END CREATING ADDITIONAL EFFECTS
 
@@ -357,5 +362,4 @@
       if(myShip_){
         COUT(3) << "requesting focus for camera" << std::endl;
-        this->setBacksync(true);
         //CameraHandler::getInstance()->requestFocus(cam_);
         if(this->isExactlyA(Class(SpaceShip))){
@@ -463,5 +467,5 @@
             }
 
-            projectile->setBacksync(true);
+            projectile->setObjectMode(0x3);
             this->timeToReload_ = this->reloadTime_;
         }
Index: /code/trunk/src/util/CMakeLists.txt
===================================================================
--- /code/trunk/src/util/CMakeLists.txt	(revision 1750)
+++ /code/trunk/src/util/CMakeLists.txt	(revision 1751)
@@ -3,4 +3,5 @@
   Clipboard.cc
   Error.cc
+  CRC32.cc
   ExprParser.cc
   Math.cc
Index: /code/trunk/src/util/CRC32.cc
===================================================================
--- /code/trunk/src/util/CRC32.cc	(revision 1751)
+++ /code/trunk/src/util/CRC32.cc	(revision 1751)
@@ -0,0 +1,56 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CRC32.h"
+
+
+void calcCRCBit(uint32_t &crc32, int bit){
+    int hbit;
+ 
+    hbit=(crc32 & 0x80000000) ? 1 : 0;
+    if (hbit != bit)
+      crc32=(crc32<<1) ^ UTIL_CRC32POLY;
+    else
+      crc32=crc32<<1;
+  }
+
+  uint32_t calcCRC(unsigned char *data, unsigned int dataLength){
+    uint32_t crc32=0;
+    for(unsigned int i=0; i<dataLength; i++){
+      calcCRCBit(crc32, (data[i]&0x1)>>0); // 1st bit
+      calcCRCBit(crc32, (data[i]&0x2)>>1); // 2nd bit
+      calcCRCBit(crc32, (data[i]&0x3)>>2); // 3rd bit
+      calcCRCBit(crc32, (data[i]&0x4)>>3); // 4th bit
+      calcCRCBit(crc32, (data[i]&0x5)>>4); // 5th bit
+      calcCRCBit(crc32, (data[i]&0x6)>>5); // 6th bit
+      calcCRCBit(crc32, (data[i]&0x7)>>6); // 7th bit
+      calcCRCBit(crc32, (data[i]&0x8)>>7); // 8th bit
+    }
+    return crc32;
+  }
+
Index: /code/trunk/src/util/CRC32.h
===================================================================
--- /code/trunk/src/util/CRC32.h	(revision 1751)
+++ /code/trunk/src/util/CRC32.h	(revision 1751)
@@ -0,0 +1,41 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Util_CRC_H__
+#define _Util_CRC_H__
+
+#include <iostream>
+
+#define UTIL_CRC32POLY 0x04C11DB7 /* CRC-32 Polynom */
+
+void calcCRCBit(uint32_t &crc32, int bit);
+
+uint32_t calcCRC(unsigned char *data, unsigned int dataLength);
+
+
+#endif /* _Util_CRC_H__ */
